Windows XP で VC 6.0、Purify、PC-Lint、Quantify を使用してコンソール アプリケーションを開発しています。VC6 は Windows 7 および 8 では動作しません。Windows 8 にアップグレードする場合の開発環境のオプションを調べました。アプリケーションは標準の C++ コンソール アプリケーションです。ほぼすべてのユーザーが Linux を使用しています。クロスプラットフォームの C++ 開発で VC++ Pro 2013 または 2012 を使用した経験のある人はいますか? 具体的には、メモリ境界チェック、メモリ リーク チェック、およびコード パフォーマンス分析 (各関数にかかる時間) を実行できますか?
1 に答える
ビジュアル C++ 2013 は、Purify と Quantify が行うことを実行できますか?
まあ、「相手ができることは何でもできる」というほどではありません。それは交差点のようなものであり、それらすべてを使用して最大限のカバレッジを取得します.
Purify はランタイム チェッカーであるため、通常、Visual Studio の組み込みメモリ チェック機能よりも優れています。ただし、Purify は静的分析を行わないため、Visual Studio を使用する必要があります。その 1 つの大きなパートナーシップ。
開発環境のオプションを検討しました... 私たちのアプリケーションは [クロスプラットフォーム] 標準の C++ コンソール アプリケーションです。
The Bike Shedding が始まります... 移植可能なコードを書いているので、これは絶好の機会です。非常に多くの人が 1 つのプラットフォームで実行されるコードを作成するため、他のプラットフォームの他のツールからの診断が失われます。
以下はすべて無料です (Visual Studio Enterprise での Enterprise Code Analysis を除く)。このプロセスを問題なく完了することができれば、かなりしっかりしたコードを作成できます。
ウィンドウズ
Visual Studio (任意のエディション) を使用し、警告を表示します。とが含ま/WAll
れ/W4
ます。Visual Studio Enterprise をお持ちの場合は、必ず Enterprise Code Analysis を追加するか、/analyze
スイッチを追加してください。
Visual Studio で基本的なメモリ チェックを行います。最新の Purity がどのように機能するかはわかりません。(私はクロスプラットフォームのコードを書き、負荷の高いメモリ チェックに Linux を使用しているため、使用しません)。
Windows プラットフォームで行うべきことは他にもあります。OWASP のC-Based Toolchain Hardeningで、開発ツールチェーンに関する議論を見つけることができます。
Linux
GCC、Clang、および ICC を必ずサポートしてください。-Wall
それらを使用するときは、 、-Wextra
、およびを含む警告を必ず上げて-Wconversion
ください。GCC は主力であり、コードはおそらく GCC 上でうまく動作します。ICC は Intel のコンパイラであり、未定義の動作を削除することについて冷酷です。ICC でコードが壊れる場合は、おそらくコンパイラ/オプティマイザーが未定義の動作を削除したためです (問題のあるコードを見つける方法については、以下の Clang の未定義のサニタイザーを参照してください)。
Clang 3.3 は、そのサニタイザーで本当に輝いています (Clang 3.2 以下にはサニタイザーがありません)。と を必ず実行して-fsanitize=address
ください-fsanitize=undefined
。サニタイザーはランタイム チェッカーを追加し、実行中に違反を探します。セルフテストは多ければ多いほど良いです。サニタイザーの完全なリストは、Clang の Controlling Code Generationにあります。
Clang 3.3 のレシピは以下のとおりです。それらには、Clang をフェッチする方法、Clang をホットにビルドする方法、サンタイザーを使用してテストを実行する方法が含まれます。
GCC、Clang、および ICC でのコンパイルが完了したら、Valgrind でプログラムを実行します。Valgrind は、もう 1 つの動的メモリ チェッカーです。
Linux プラットフォームでやるべきことは他にもあります。OWASP のC-Based Toolchain Hardeningで、開発ツールチェーンに関する議論を見つけることができます。
最新の Clang 3.3 をダウンロードしてビルドするには:
wget http://llvm.org/releases/3.3/llvm-3.3.src.tar.gz
wget http://llvm.org/releases/3.3/cfe-3.3.src.tar.gz
wget http://llvm.org/releases/3.3/compiler-rt-3.3.src.tar.gz
# wget http://llvm.org/releases/3.3/lldb-3.3.src.tar.gz
tar xvf llvm-3.3.src.tar.gz
cd llvm-3.3.src/tools
tar xvf ../../cfe-3.3.src.tar.gz
mv cfe-3.3.src clang
# tar xvf ../../lldb-3.3.src.tar.gz
# mv lldb-3.3.src/ lldb
cd ..
cd projects
tar xvf ../../compiler-rt-3.3.src.tar.gz
mv compiler-rt-3.3.src/ compiler-rt
cd ..
./configure --enable-optimized --prefix=/usr/local
make -j4
# Pause to wait for the password prompt
read -p "Press [Enter] key to install..."
# Begin install
sudo make install
# Install does not copy asan_symbolize.py
sudo cp projects/compiler-rt/lib/asan/scripts/asan_symbolize.py /usr/local/bin
# Install does not install scan-build and scan-view
# Perform the copy, and/or put them on-path
sudo mkdir /usr/local/bin/scan-build
sudo cp -r tools/clang/tools/scan-build /usr/local/bin
sudo mkdir /usr/local/bin/scan-view
sudo cp -r tools/clang/tools/scan-view /usr/local/bin
Clang を使用するには:
export CC=/usr/local/bin/clang
export CXX=/usr/local/bin/clang++
export CFLAGS="-g3 -fsanitize=undefined"
export CXXFLAGS="-g3 -fsanitize=undefined -fno-sanitize=vptr"
./configure
make
make check | /usr/local/bin/asan_symbolize.py
メモリの問題が発生した場合は、次のようになります ( Squid 3.3.9 Self Test Failures on Mac OS X 10.8から取得)。
==76794==ERROR: AddressSanitizer: global-buffer-overflow on address
0x000105ad50d2 at pc 0x105a364ab bp 0x7fff5a23f720 sp 0x7fff5a23f718
READ of size 19 at 0x000105ad50d2 thread T0
#0 0x105a364aa in MemBuf::append MemBuf.cc:248
#1 0x105a4ef57 in testHttpReply::testSanityCheckFirstLine
testHttpReply.cc:197
#2 0x1068d71d1 in CppUnit::TestCaseMethodFunctor::operator()() const (in
libcppunit-1.12.1.dylib) + 33
#3 0x1068cd9a3 in CppUnit::DefaultProtector::protect(CppUnit::Functor
const&, CppUnit::ProtectorContext const&) (in libcppunit-1.12.1.dylib) + 35
#4 0x1068d4d88 in CppUnit::ProtectorChain::ProtectFunctor::operator()()
const (in libcppunit-1.12.1.dylib) + 24
#5 0x1068d45e8 in CppUnit::ProtectorChain::protect(CppUnit::Functor const&,
CppUnit::ProtectorContext const&) (in libcppunit-1.12.1.dylib) + 456
#6 0x1068dcf78 in CppUnit::TestResult::protect(CppUnit::Functor const&,
CppUnit::Test*, std::string const&) (in libcppunit-1.12.1.dylib) + 56
#7 0x1068d6d1d in CppUnit::TestCase::run(CppUnit::TestResult*) (in
libcppunit-1.12.1.dylib) + 285
#8 0x1068d77b6 in
CppUnit::TestComposite::doRunChildTests(CppUnit::TestResult*) (in
libcppunit-1.12.1.dylib) + 54
#9 0x1068d76be in CppUnit::TestComposite::run(CppUnit::TestResult*) (in
libcppunit-1.12.1.dylib) + 30
#10 0x1068d77b6 in
CppUnit::TestComposite::doRunChildTests(CppUnit::TestResult*) (in
libcppunit-1.12.1.dylib) + 54
#11 0x1068d76be in CppUnit::TestComposite::run(CppUnit::TestResult*) (in
libcppunit-1.12.1.dylib) + 30
#12 0x1068dcde1 in CppUnit::TestResult::runTest(CppUnit::Test*) (in
libcppunit-1.12.1.dylib) + 33
#13 0x1068de9a5 in CppUnit::TestRunner::run(CppUnit::TestResult&,
std::string const&) (in libcppunit-1.12.1.dylib) + 53
#14 0x105a55a97 in main testMain.cc:31
#15 0x7fff90af07e0 in start (in libdyld.dylib) + 0
#16 0x0
0x000105ad50d2 is located 46 bytes to the left of global variable '.str28' from
'tests/testHttpReply.cc' (0x105ad5100) of size 16
'.str28' is ascii string 'HTTP/1.1 -000
0x000105ad50d2 is located 0 bytes to the right of global variable '.str27' from
'tests/testHttpReply.cc' (0x105ad50c0) of size 18
'.str27' is ascii string 'HTTP/1.10 Okay
そして、未定義の動作と不正なシフトは次のようになります (Postgres のClang 3.3 の調査結果と不正なシフトから取得) :
make check
...
vacuuming database template1 ... localtime.c:127:20: runtime error:
left shift of negative value -1
pg_lzcompress.c:601:5: runtime error: left shift of negative value -68
pg_lzcompress.c:601:5: runtime error: left shift of negative value -68
pg_lzcompress.c:385:16: runtime error: left shift of negative value -68
pg_lzcompress.c:615:4: runtime error: left shift of negative value -68
Intel の ICC で失敗する場合は、必ず Clang で実行してください-fsanitize=undefined
。ICC は問題のあるコードを黙って削除するからです。問題のあるコードを見つけるために私が見つけた最も簡単な方法です。