我有来自网络的这段代码,我想对其进行测试以与堆一起使用,以了解其如何存储地址。
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
struct internet {
int priority;
char *name;
};
void winner()
{
printf("and we have a winner @ %d\n", time(NULL));
}
int main(int argc, char **argv)
{
struct internet *i1, *i2, *i3;
i1 = malloc(sizeof(struct internet));
i1->priority = 1;
i1->name = malloc(8);
i2 = malloc(sizeof(struct internet));
i2->priority = 2;
i2->name = malloc(8);
strcpy(i1->name, argv[1]);
strcpy(i2->name, argv[2]);
printf("and that's a wrap folks!\n");
}
我使用以下命令进行编译:
gcc -g -o heap1 heap.c
然后我运行gdb:
gdb heap1
现在,由于代码需要从参数中输入,因此当我使用malloc时,它应该在堆上显示错误的分段以及地址。但是我机器上的gcc无法打印出来。我不确定它是版本还是需要特殊配置才能为有错误的变量打印该堆地址存储器。
gcc版本是9.2.1,而gdb是8.3。
这是gdb run命令的输出:
Program received signal SIGSEGV, Segmentation fault.
__strcpy_avx2 () at ../sysdeps/x86_64/multiarch/strcpy-avx2.S:301
301 ../sysdeps/x86_64/multiarch/strcpy-avx2.S: No such file or directory.
它应该在我使用malloc的同时打印分段错误以及堆上的地址
我不确定为什么,您认为应该这样做。 您的代码中没有任何内容可以打印任何地址,因此我假设您是在谈论gdb
打印地址。也不要求gdb
执行此操作。 特别是,因为堆地址绝对没有错误。您遇到的问题在于strcpy
中的源地址,即argv[]
值。
相反,它告诉您有一个SEGV,它提示了确切的源代码行,然后通知您无法找到发生该函数的源代码(这意味着您只需要调试汇编代码即可)。
如果您具有strcpy
函数的可用源,那么毫无疑问,您将能够检查局部变量和传递的参数以找出问题所在。否则,您将不得不依靠了解调用约定,并确定从代码到崩溃代码的路径。
或者,您可以以不使用会引起问题的变量的方式编写代码。换句话说,在盲目使用argc
之前检查argv
。
要实际上在gdb
中显示任意表达式,您只需使用print
命令,该命令从内存中允许非常复杂的规范,例如:
print ((int*)X)[14]
当然,如果没有您所在级别的源文件,您将被寄存器和内存地址所困扰。为了帮助gdb
找出这些文件,请查看set directories
命令。