C++Test静态分析时,抛出”解析文件失败”异常的原因及解决办法

C++Test静态分析时,抛出”解析文件失败”错误的原因及解决方法

C++Test可以执行代码静态分析,检验代码是否符合MisraC++等规则。本文讨论了C++Test进行静态分析时候,抛出解析文件失败错误的原因,并提出绕过去的方法。

本文内容基于以下软件环境Windows 7 / Visual Studio 2010 / C++Test9.0VS插件版

时间仓促,本文文字没有认真组织,以说明清楚问题为主,希望对遇到同样问题的同行提供一些思路。

C++Test静态分析时,不是调用cl.exe完成代码解析

C++Test要分析代码,必然要先解析代码。一开始我认为C++Test是用本地编译器来完成代码解析(比如VC的cl.exe),然而实际上并不是这样。它执行静态分析的流程是:

1.      vs 2010调用C++Test提供的cwc.exe

2.      cwc.exe调用cl.exe,对源文件预处理。注意,仅仅是预处理。

3.      cwc.exe对预处理的代码进行解析。

 

以下是在vs 2010中执行静态分析,系统中相关进程活动情况。尤其请注意cl.exe的命令行参数/E。根据msdn,/E的作用是:“Preprocesses C and C++ source files and copies the preprocessedfiles to the standard output device. The/E option suppressescompilation. You must resubmit the preprocessed file for compilation.”也就是说,C++Test仅仅调用cl做预处理。

另外,调用cl.exe进行预处理也是需要在用户中指定的,VC中默认是调用C++Test自身的预处理器。

 

VS中启动C++Test静态分析功能后,系统进程的活动情况记录表:

序号

Time of Day

Process Name

PID

Operation

Path

Image Path

1

37:33.4

devenv.exe

11620

Process Create

C:\Program Files (x86)\Parasoft\C++test for Visual Studio\9.0\engine\bin\cwc.exe

C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe

2

37:33.4

cwc.exe

14320

Process Start

C:\Program Files (x86)\Parasoft\C++test for Visual Studio\9.0\engine\bin\cwc.exe

3

37:33.9

cwc.exe

14320

Process Create

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\cl.exe

C:\Program Files (x86)\Parasoft\C++test for Visual Studio\9.0\engine\bin\cwc.exe

4

37:33.9

cl.exe

5324

Process Start

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\cl.exe

5

37:36.9

cl.exe

5324

Process Exit

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\cl.exe

6

37:40.3

cwc.exe

14320

Process Exit

C:\Program Files (x86)\Parasoft\C++test for Visual Studio\9.0\engine\bin\cwc.exe

 


上表中cwc.exe进程的命令行

"C:\Program Files (x86)\Parasoft\C++test for Visual Studio\9.0\engine\bin\cwc.exe" "--psrc=C:\Users\vigour\AppData\Local\Temp\cs_global_config35632.tmp" "--psrc=C:\Users\vigour\AppData\Local\Temp\cs_file_config35635.tmp" "--psrc=C:\Users\vigour\AppData\Local\Temp\cs_project_config35634.tmp" "--ltm=1066263b" "-Zspawn" "--report-violations-in-utf8=on" "--summary-run-temp-dir=C:\Users\vigour\AppData\Local\Temp\parasoft\globalAnalysisTemp" "--native-options-start" "-IC:\Program Files (x86)\Parasoft\C++test for Visual Studio\9.0\engine\runtime\include" "/nologo" "/Od" "/Id:\boost_1_53_0\\" "/Gm" "/EHsc" "/RTC1" "/MDd" "/DWIN32" "/D_DEBUG" "/D_CONSOLE" "/D_UNICODE" "/DUNICODE" "/GR-" "/W3" "/nologo" "/ZI" "/Gd" "/FC" "-DPARASOFT_CPPTEST" "-I." "-w" "--native-options-end" "D:\hy\codes\tools\MemoryLeaks\MemoryLeaks\MemoryLeaks.cpp" "--fileName=D:\hy\codes\tools\MemoryLeaks\MemoryLeaks\MemoryLeaks.cpp" "--compiler-cfg-file=C:\Program Files (x86)\Parasoft\C++test for Visual Studio\9.0\engine\etc\compilers\vc_10_0\cpp.psrc" "--preprocessorExecutable=cl.exe"

上表中cl.exe进程的命令行

cl.exe "-IC:\Program Files (x86)\Parasoft\C++test for Visual Studio\9.0\engine\runtime\include" "/Id:\boost_1_53_0\\" /EHsc /MDd /DWIN32 /D_DEBUG /D_CONSOLE /D_UNICODE /DUNICODE /GR- -DPARASOFT_CPPTEST -I. -w -E -Tp "D:\hy\codes\tools\MemoryLeaks\MemoryLeaks\MemoryLeaks.cpp"

 

C++Test静态分析的时候会错误的不能解析源文件

如上文所述,C++Test静态分析是自己解析C++代码,类似于做了一个C++的编译器。然而这个编译器并不完善,表现为,在VS 2010中能正常编译的代码,C++Test解析却会出错。这个时候,我想到的方法只能是通过PARASOFT_CPPTEST预编译指令绕过去。

以下的代码是例子。请注意其中的#ifdef PARASOFT_CPPTEST部分。

#include <boost/interprocess/managed_shared_memory.hpp>

#include <boost/interprocess/allocators/allocator.hpp>

#include <boost/interprocess/containers/deque.hpp>

#include <boost/interprocess/containers/vector.hpp>

#include <boost/interprocess/containers/string.hpp>

 

 

namespace ipc= boost::interprocess ;

 

typedef ipc::managed_shared_memory                                      SharedMemory;

typedef ipc::managed_windows_shared_memory                              WinSharedMemory;

typedef SharedMemory::segment_manager                                   SegmentManager;

 

typedef ipc::allocator<void, SegmentManager>                            VoidAllocator;

typedef ipc::allocator<char, SegmentManager>                            CharAllocator;

 

typedef ipc::basic_string<char, std::char_traits<char>, CharAllocator>  CharString;

typedef ipc::allocator<CharString, SegmentManager>                      CharStringAllocator;

typedef ipc::vector<CharString, CharStringAllocator>                    CharStringVector;

 

 

class EVENT_NOTIFY

{

public:

    EVENT_NOTIFY(VoidAllocator& alloc): strEventName(alloc), vctEventParas(alloc){

    }

 

 

    // 这段代码是不需要的,但是少了它,C++Test静态检查、解析文件会失败。

#ifdef PARASOFT_CPPTEST

    const EVENT_NOTIFY& operator=(const EVENT_NOTIFY& src){

        strEventName =src.strEventName;

        vctEventParas = src.vctEventParas;

        return *this;

    }

#endif

 

    CharString                      strEventName ; 

    CharStringVector                vctEventParas ;    

};

 

int _tmain(int argc, _TCHAR* argv[])

{

    SegmentManager* ps = 0;

    VoidAllocator alloc(ps);

 

    typedef ipc::allocator<EVENT_NOTIFY, SegmentManager> EVENT_NOTIFY_Allocator;

    boost::interprocess::deque<EVENT_NOTIFY, EVENT_NOTIFY_Allocator> d(alloc);

 

    EVENT_NOTIFY aa(alloc);

    d.push_back(aa);

    return 0;

}