我正在开发一个高度多线程的项目,并且想知道是否有办法让编译器标记对 C 库的非可重入调用的使用(例如 strtok_r 的 strtok intsead)?如果没有,是否有一个不可重入的调用列表,以便我可以定期 grep 通过我的代码库?
一个相关的问题是,是否有办法标记 3d 方库使用不可重入调用。
我假设可重入意味着线程安全,但不一定反过来。是否有充分的理由在线程项目中使用不可重入调用?
我正在开发一个高度多线程的项目,并且想知道是否有办法让编译器标记对 C 库的非可重入调用的使用(例如 strtok_r 的 strtok intsead)?如果没有,是否有一个不可重入的调用列表,以便我可以定期 grep 通过我的代码库?
一个相关的问题是,是否有办法标记 3d 方库使用不可重入调用。
我假设可重入意味着线程安全,但不一定反过来。是否有充分的理由在线程项目中使用不可重入调用?
对于源代码,您可能会坚持每个源文件都包含以下行:
#include <beware.h>
在 C 头文件之后,然后beware.h
头文件包含:
#define strtok unsafe_function_call_detected_strtok
#define getenv unsafe_function_call_detected_getenv
或其他一些不太可能是真实函数的合适名称集。这将导致编译和/或链接器错误。
对于图书馆来说,这有点困难。您可以考虑使用nm
提取每个目标文件中所有未解析的名称,并确保不调用任何不安全的名称。
这不会是编译器这样做,但它很容易合并到构建脚本中。请参阅以下成绩单:
$ cat qq.c
#include <stdio.h>
int main (int argc, char *argv[]) {
printf ("Hello, world.\n");
return 0;
}
$ gcc -c -o qq.o qq.c
$ nm qq.o
00000000 b .bss
00000000 d .data
00000000 r .rdata
00000000 t .text
U ___main
00000000 T _main
U _puts
您可以使用标记看到该输出中未解析的符号U
(并且gcc
非常偷偷地决定使用puts
而不是printf
因为我给了它一个没有格式化命令的常量字符串)。
是否有一个不可重入的调用列表,以便我可以定期通过我的代码库进行 grep?
我查看了 GNU libc 函数列表,并选择了带有 _r 的函数列表。这是清单。
asctime, 地穴, ctime, drand48, ecvt, 加密, erand48, fcvt, fgetgrent, fgetpwent, getdate, getgrent, getgrgid, getgrnam, gethostbyaddr, gethostbyname2, gethostbyname, getmntent, getnetgrent, getpwent, getpwnam, getpwuid, getutent, getutid, getutline, gmtime, hcreate, hdestroy, hsearch, initstate, jrand48, lcong48, lgamma, lgammaf, lgammal, localtime, lrand48, mrand48, nrand48, ptsname, qecvt, qfcvt, rand, random, readdir64, readdir, seed48, setkey, setstate, srand48,随机,strerror,strtok,tmpnam,ttyname
解决您问题的第二部分:
非重入调用可以以赋予它们性能优势的方式实现。在这种情况下,如果您知道您只是从一个线程(或在一个关键部分内)进行这些调用,并且它们是您的瓶颈,那么选择不可重入调用是有意义的。但是,只有在有性能测量表明这样做很关键时,我才会这样做……并仔细记录它……
对于二进制文件,您可以使用LD_PRELOAD
拦截您喜欢的任何 C 库函数并采取任何您想要的操作(中止、记录错误但继续等)
在开发过程中,你也可以使用 valgrind 来做同样的事情。
Cppcheck将标记使用不可重入标准库函数。启用可移植性警告以启用此检查。
有关 Cppcheck 将标记的函数列表,请参阅non_reentrant_functions_list
checknonreentrantfunctions.h 。
Cppcheck 将发出的消息示例:
调用了不可重入函数“strtok”。对于线程安全应用程序,建议使用可重入替换函数“strtok_r”。(可移植性:nonreentrantFunctionsstrtok)