繁体   English   中英

有没有办法标记使用非重入C库调用?

[英]Is there a way to flag the use of non-reentrant C library calls?

我正在研究一个多线程的项目,并且想知道是否有办法让编译器标记使用对C库的非重入调用(例如strtok_r的strtok intsead)? 如果没有,是否有一个不可重入的调用列表,所以我可以定期查看我的代码库?

一个相关的问题是,是否有办法标记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,crypt,ctime,drand48,ecvt,encrypt,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, srandom,strerror,strtok,tmpnam,ttyname

解决问题的第二部分:

可以以给予性能优势的方式实现非可重入调用。 在这种情况下,如果你知道你只是从一个线程(或在一个关键部分内)进行这些调用,并且它们是你的瓶颈,那么选择不可重入的调用是有意义的。 但是,如果有性能测量表明这样做是至关重要的,我只会这样做......并仔细记录它。

Cppcheck将标记使用非重入标准库函数。 启用可移植性警告以启用此检查。

请参阅non_reentrant_functions_list中的non_reentrant_functions_list以获取Cppcheck将标记的函数列表。

Cppcheck将发出的消息示例:

非重入函数'strtok'调用。 对于线程安全应用程序,建议使用可重入替换函数'strtok_r'。 (可移植性:nonreentrantFunctionsstrtok)

对于二进制文件,您可以使用LD_PRELOAD拦截您喜欢的任何C库函数并执行您想要的任何操作(中止,记录错误但继续执行等)

在开发过程中,您也可以使用valgrind来做同样的事情。

有关示例代码和参考,请参阅如何拦截linux sys调用的答案

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM