0

argv在AIX 6.1 上,我有一段代码在NULL调用strdup. 完全相同的代码在 Linux、HPUX 和 Solaris 上运行。

这是我获得核心转储的生产代码的摘录:

Makefile    
....
    CFLAGS += -I$(SERVER)/shared/interfaces \
              -DADAPTER_BUILD_DATE="\"$(shell date)\"" 
....

全球.c

...
char *z_adapter_build_date = NULL;
...

共享.c

...
extern char *z_adapter_build_date;
...

测试.c

   int main(int l_argc, char **l_argv)
{

    char                *lbasename;
    char                *ltmp;
    z_adapter_build_date = (char *)ADAPTER_BUILD_DATE;

    ltmp = strdup(l_argv[0]);
    lbasename = basename(ltmp);
    if ((zprogname = strdup(lbasename)) == NULL)
    {
        printf("strdup failed:\n");
        exit(1);
    }

....


$ dbx ./test
warning: tpm_builtin_fn.cc is newer than /xps/ceal_800/rel/server/lib/libsql.so
warning: trans_tux.cc is newer than /xps/ceal_800/rel/server/lib/libsql.so
warning: varmap.cc is newer than /xps/ceal_800/rel/server/lib/libsql.so

(dbx) [1] stop in main
(dbx)
(dbx) r 1
[1] stopped in main at line 113 in file "/u01/xps/800/src/test.c" ($t1)
  113       z_adapter_build_date = (char *)ADAPTER_BUILD_DATE;
(dbx) p l_argv[1]
"1"
(dbx) n
stopped in main at line 115 in file "/u01/xps/800/src/test.c" ($t1)
  115       ltmp = strdup(l_argv[0]);
(dbx) p l_argv[1]
(nil)

但是,可能是一个红鲱鱼,上面的 cc 文件版本存在不匹配,我猜这可能是一个原因。我不太确定是什么导致该值变为 NULL。

4

2 回答 2

1

这看起来非常可疑:

-DADAPTER_BUILD_DATE=$(shell date)  

,尤其是与

z_adapter_build_date = (char *)ADAPTER_BUILD_DATE;

您显然想注入一个日期字符串ADAPTER_BUILD_DATE,但我不知道您提供的内容将如何为您提供,因为我看不到将扩展为字符串文字所需的引号从哪里来。我认为它根本不会在 Linux 上编译,但如果dateAIX 上的命令返回全数字日期,那么它可能会在那里编译。您可以考虑捕获预处理的输出以查看实际发生的情况。

请注意,顺便说一句,如果-DADAPTER_BUILD_DATE 确实扩展为字符串文字,那么您不需要将其强制转换为char *. 在文字衰减为指针之后,它应该已经是它的类型了。

无论如何,如果您尝试通过该宏注入字符串文字,那么您可能会在 makefile 中添加类似这样的内容:

-DADAPTER_BUILD_DATE='"$(shell date)"'

双引号需要通过宏定义,但选项需要通过shell引号删除。单引号保护双引号不被引号删除,而它们本身被删除。 make本身忽略所有引号。

于 2016-09-13T20:35:53.077 回答
0

如果z_adapter_build_date是某个 C++ 对象,使得对其的赋值会触发函数调用(赋值运算符来自等),则可能const char *是其中一些函数与堆栈上的字符串缓冲区一起工作,这些缓冲区正在被溢出,从而破坏了其中的局部变量。main溢出寄存器并进入堆栈帧。

于 2016-09-13T20:29:48.403 回答