我正在使我的应用程序线程安全。步骤之一是同步访问或消除全局变量的使用。我正在使用 Visual Studio。我找不到任何好方法来查找代码库中的所有全局变量。创建一个好的文本搜索模式是不可能的,而且我找不到任何有用的工具。大家知道有什么好的办法吗?它可以是源代码分析工具或二进制文件分析器。
这可能有帮助:
我已使用 Visual Studio 2010 及更高版本检查过这一点。
编辑:按照评论中Ajay的建议,您还可以对项目进行分组。对于项目分组:
一种选择可能是让链接器生成映射文件(Visual Studio 中的 /MAP)。
您将获得每个二进制文件的 .map 文件,其中包含两个部分:
段表
Start Length Name Class
0001:00000000 00010000H .textbss DATA
0002:00000000 000034b4H .text CODE
0003:00000000 00000104H .CRT$XCA DATA
0003:00000104 00000104H .CRT$XCAA DATA
0003:00000208 00000104H .CRT$XCZ DATA
0003:0000030c 00000104H .CRT$XIA DATA
...
符号列表(函数和数据)
Address Publics by Value Rva+Base Lib:Object
0000:00000000 ___safe_se_handler_count 00000000 <absolute>
0000:00000000 ___safe_se_handler_table 00000000 <absolute>
0000:00000000 ___ImageBase 00400000 <linker-defined>
0001:00000000 __enc$textbss$begin 00401000 <linker-defined>
0001:00010000 __enc$textbss$end 00411000 <linker-defined>
0002:000003a0 _wmain 004113a0 f console4.obj
...
您可以通过段列表中的“代码”/“数据”名称来区分函数和变量。
优点:您将获得所有未被链接器删除的符号,甚至是库中的符号。
缺点:您将获得链接器未删除的所有符号,甚至是库中的符号。我不知道有什么工具可以自动进行代码/数据分离。
我知道http://code.google.com/p/data-race-test/wiki/ThreadSanitizer程序(谷歌的产品)可以在Windows和编译代码上运行。它是动态检测程序(如 valgrind 或有点像 qemu/virtualbox),它为内存访问添加了一些检查。它将尝试发现一些线程问题。您可以在threadsanitizer的控制下运行您的程序。动态转换和检测代码将会导致速度减慢(速度减慢 20 倍至 50 倍)。但有些问题会自动检测到。
它还允许您在源代码中注释一些自定义同步函数。
程序的 Wiki 有指向其他线程竞争检测器的链接:http://code.google.com/p/data-race-test/wiki/RaceDetectionLinks
cppclean是一个可以帮助你的静态分析工具。来自文档:
cppclean finds global/static data that are potential problems when using threads.
下面是一个带有静态局部变量和全局变量的简单示例。
./example.h:
void foo();
./example.cpp:
#include "example.h"
int globalVar = 42;
void foo(){
static int localStatic = 0;
localStatic++;
}
打开终端并运行 cppclean,如下所示:
$ cppclean --include-path . example.cpp
example.cpp:3: static data 'globalVar'
example.cpp:6: static data 'localStatic'
你们都把事情搞得太复杂了。
1. 将每个文件的代码(一次一个与其他文件分开)复制到字符串或宽字符串等,然后解析出从“{”到“}”不包含的所有内容。将结果保存到外部文件。第一次之后,然后追加到该文件。
2. 即使在所有解析之后剩下的内容总共有 1,000 行,其中也包含了所有全局变量(取决于您如何创建全局变量)。如果您通过名称空间等创建它们,则返回并解析它们。我怀疑大多数程序员是否会拥有 1,000 个全局变量,但对于某些应用程序来说,这可能就是他们所使用的。如果此时您没有太多结果,请手动编辑结果的文本文件。
我发现这个网站上 90% 以上的答案可能都过于复杂,只会占用 CPU 时间和内存空间。保持简单。
您可能会发现有一个 globals.h 文件很方便,您可以尽早加载该文件并将大部分或全部全局变量保留在那里。看来是时候进行大量清理工作了。
在
clang-query
中,所有全局变量都可以使用列出
match varDecl(hasGlobalStorage())
举个更复杂的例子,找到所有指向
my_type
, 的指针的全局变量
match varDecl(hasGlobalStorage(), hasType(pointerType(pointee(hasUnqualifiedDesugaredType(recordType(hasDeclaration(cxxRecordDecl(hasName("my_type")))))))))
这找到了所有
static
函数内的变量static
类的成员变量请参阅仅在输入文件上运行 clang-query 了解如何限制结果。
请注意,如果全局变量出现在从未实例化的模板中,上面将列出它,即使编译的代码中实际上不存在这样的全局变量。