AIX中的分段错误,用于argv的空值

时间:2016-09-13 18:51:34

标签: c segmentation-fault aix dbx

在AIX 6.1上,我有一段代码,argv在调用NULL后以某种方式设置为strdup。完全相同的代码适用于Linux,HPUX和Solaris。

以下是我正在获取核心转储的生产代码的摘录:

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

global.c

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

shared.c

...
extern char *z_adapter_build_date;
...

test.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。

2 个答案:

答案 0 :(得分:1)

这看起来非常可疑:

-DADAPTER_BUILD_DATE=$(shell date)  

,特别是与

结合使用时
z_adapter_build_date = (char *)ADAPTER_BUILD_DATE;

你显然想要注明一个日期字符串,但我不知道你所呈现的内容会给你什么,因为我不知道哪里会有报价使ADAPTER_BUILD_DATE的扩展成为字符串文字所需的标记。我不认为它会在Linux上编译,但是如果AIX上的date命令返回一个全数字日期,那么它可能会在那里编译。您可以考虑捕获预处理的输出以查看实际发生的情况。

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

无论如何,如果您尝试通过该宏注入字符串文字,那么您可能会在makefile中更像这样:

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

双引号需要进入宏定义,但该选项需要通过shell引用删除。单引号保护引号删除中的双引号,而不是删除引号。 make本身会忽略所有引号。

答案 1 :(得分:0)

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