Мы разрабатываем консольное приложение с использованием VC 6.0, Purify, PC-Lint и Quantify для Windows XP. VC6 не будет работать в Windows 7 и 8. Я рассмотрел наши варианты для сред разработки, если бы нам пришлось перейти на Windows 8. Наше приложение является стандартным консольным приложением C ++. Практически все наши пользователи работают на Linux. У кого-нибудь есть опыт работы с VC ++ Pro 2013 или 2012 для кроссплатформенной разработки c ++? В частности, может ли он выполнять проверку границ памяти, проверку утечки памяти и анализ производительности кода (сколько времени занимает каждая функция)?
Может ли Visual C ++ 2013 делать то, что делают Purify и Quantify?
Ну, это не так много, «можно сделать все, что делает другой». Это больше похоже на пересечение, и использовать их все, чтобы получить наибольшее освещение.
Purify — это средство проверки времени выполнения, поэтому оно обычно превосходит встроенные средства проверки памяти Visual Studio. Но Purify не выполняет статический анализ, поэтому вам нужно будет использовать Visual Studio. Это одно большое партнерство.
Я посмотрел на наши варианты для сред разработки
…
Наше приложение является [кроссплатформенным] стандартным консольным приложением C ++.
Начинается потеря велосипеда … Это прекрасная возможность, поскольку вы пишете переносимый код. Так много людей пишут код, который выполняется на одной платформе, и теряют диагностику из других инструментов на других платформах.
Все, что ниже, является бесплатным (кроме анализа корпоративного кода в Visual Studio Enterprise), и если вы сможете выполнить процесс без ошибок, у вас будет достаточно надежный код.
Windows
Используйте Visual Studio (любой выпуск) и включите предупреждения. Они включают /WAll
а также /W4
, Если у вас есть Visual Studio Enterprise, обязательно добавьте Enterprise Code Analysis или добавьте /analyze
переключатель.
Вы получаете базовую проверку памяти в Visual Studio. Я не уверен, как последняя чистота работает с ним. (Я не использую его, потому что я пишу кроссплатформенный код и использую Linux для проверки памяти в тяжелых условиях).
Есть и другие вещи, которые вы должны делать для платформы Windows. Вы можете найти обсуждение инструментов разработки в OWASP. Укрепление цепочки инструментов на основе С.
Linux
Обязательно поддержите GCC, Clang и ICC. При их использовании обязательно проверяйте предупреждения, в том числе -Wall
, -Wextra
, а также -Wconversion
, GCC является основой, и ваш код, вероятно, хорошо работает на нем. ICC является компилятором Intel и безжалостно удаляет неопределенное поведение. Если ваш код ломается под ICC, это возможно потому, что компилятор / оптимизатор удалил какое-то неопределенное поведение (см. Ниже неопределенное дезинфицирующее средство Clang о том, как найти нарушающий код).
Clang 3.3 действительно сияет своими дезинфицирующими средствами (у Clang 3.2 и ниже их нет). Обязательно бегите с -fsanitize=address
а также -fsanitize=undefined
, Дезинфицирующие средства добавляют средства проверки во время выполнения и ищут нарушения во время выполнения. Чем больше у вас тестов, тем лучше. Полный список дезинфицирующих средств доступен Генерация управляющего кода Clang.
Рецепты Clang 3.3 приведены ниже. Они включают в себя, как получить Clang, как построить Clang и как выполнить ваши тесты с помощью дезинфицирующих средств.
После завершения компиляции с GCC, Clang и ICC запустите программу под Valgrind. Valgrind — это еще одна проверка динамической памяти.
Есть и другие вещи, которые вы должны делать для платформы Linux. Вы можете найти обсуждение инструментов разработки в OWASP. Укрепление цепочки инструментов на основе С.
Чтобы загрузить и собрать 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. Ошибки самопроверки в 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
А вот как выглядит неопределенное поведение и нелегальный сдвиг (взято из Постгреса Выводы 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 будет молча удалять любой оскорбительный код. Это самый простой способ найти нарушающий код.
Других решений пока нет …