【问题标题】:Can visual c++ 2013 do what Purify and Quntify do?Visual c++ 2013 可以做 Purify 和 Quantify 做的事情吗?
【发布时间】:2014-01-18 14:57:31
【问题描述】:

我们在 Windows XP 上使用 VC 6.0、Purify、PC-Lint 和 Quantify 开发了一个控制台应用程序。 VC6 不能在 Windows 7 和 8 上运行。如果我们要升级到 Windows 8,我已经查看了我们的开发环境选项。我们的应用程序是标准 C++ 控制台应用程序。几乎我们所有的用户都在 Linux 上。有没有人有使用 VC++ Pro 2013 或 2012 进行跨平台 C++ 开发的经验?具体来说,它是否可以做内存边界检查、内存泄漏检查和代码性能分析(每个函数需要多少时间)?

【问题讨论】:

    标签: c++ visual-studio-2013 purify quantify


    【解决方案1】:

    visual c++ 2013 可以做 Purify 和 Quantify 做的事情吗?

    嗯,并不是说“一个人可以做其他人所做的一切”。它更像是一个十字路口,并使用它们来获得最大的覆盖范围。

    Purify 是一个运行时检查器,因此它的性能通常优于 Visual Studio 的内置内存检查工具。但是 Purify 不做静态分析,所以你需要使用 Visual Studio。这是一个重要的合作伙伴关系。


    我查看了我们的开发环境选项 ... 我们的应用程序是 [跨平台] 标准 C++ 控制台应用程序。

    Bike Shedding 开始了……这是一个很好的机会,因为您正在编写可移植的代码。很多人编写在一个平台上运行的代码,他们失去了来自其他平台上其他工具的诊断。

    以下所有内容都是免费的(Visual Studio Enterprise 下的 Enterprise Code Analysis 除外),如果您能够干净利落地完成该过程,那么您将拥有相当可靠的代码。

    Windows

    使用 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 是中流砥柱,您的代码可能在它上面运行良好。 ICC 是英特尔的编译器,它对删除未定义的行为毫不留情。如果您的代码在 ICC 下中断,可能是因为编译器/优化器删除了一些未定义的行为(请参阅下面的 Clang 的未定义清理程序,了解如何定位有问题的代码)。

    Clang 3.3 的消毒剂确实令人眼前一亮(Clang 3.2 及更低版本没有它们)。请务必使用-fsanitize=address-fsanitize=undefined 运行。 sanitizers 添加运行时检查器并在执行期间查找违规行为。您进行的自我测试越多越好。可通过Clang's Controlling Code Generation 获取完整的消毒剂列表。

    Clang 3.3 配方如下。它们包括如何获取 Clang、热构建 Clang,以及如何使用 santizer 执行测试。

    用 GCC、Clang 和 ICC 编译完成后,在 Valgrind 下运行程序。 Valgrind 是另一个动态内存检查器。

    对于 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 findings and Illegal Shifts)

    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 会默默地删除任何有问题的代码。这是我发现找到有问题的代码的最简单方法。

    【讨论】:

    • 奇怪的是,由于使用 unix,您不使用 Purify,在我过去作为 C 程序员的大部分时间里,Purify 只在 unix 上运行,即使它出现在 windows 上也没有那么好。
    猜你喜欢
    • 2018-07-02
    • 2021-03-02
    • 2015-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-26
    • 2014-02-25
    相关资源
    最近更新 更多