c-GDB不理解代码



我有代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
size_t foo_len (const char *s)
{
  return strlen (s);
}
int main (int argc, char *argv[])
{
  const char *a = NULL;
  printf ("size of a = %dn", foo_len (a));
  exit (0);
}

使用调试符号编译:

$ gcc example.c -g -o example

并在GDB 中运行

 $ gdb ./example
user@ubuntu:~$ gdb ./example 
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./example...done.

GDB运行

(gdb) run
Starting program: ./example

我被期望得到类似的东西

 Program received signal SIGSEGV, Segmentation fault.
 0x0000000000400527 in foo_len (s=0x0) at example.c:8
 8    return strlen (s);

但是得到了:

Program received signal SIGSEGV, Segmentation fault.
strlen () at ../sysdeps/x86_64/strlen.S:106
106 ../sysdeps/x86_64/strlen.S: No such file or directory.

问题出在哪里?

维基百科中的示例不正确?

问题是将NULL传递给strlen(),这会导致未定义的行为,从而导致崩溃。您似乎期望未定义的行为发生在代码中,在调用之前,这毫无意义。

如果你有标准库的源代码,你就可以看到它发生的源代码行;看起来您的strlen()是在汇编中编写的。当然,您可以通过要求gdb使用disassemble命令反汇编代码来查看这些说明。

还有这个:

 printf ("size of a = %dn", foo_len (a));

是错误的,您不能合法地将size_t打印为int;事实并非如此。您应该使用%zu打印size_t:类型的值

 printf("length of a = %zun", foo_len(a));

此外,谈论字符串的"大小"(而不是长度)有点令人困惑。

您的错误发生在strlen内部。要查看gdb中的完整调用堆栈,请使用命令bt进行回溯。

好吧,分段错误确实发生在strlen中,而不是您的函数中,所以您在那里看到它发生的事实是正确的。

使用您的发行版安装工具获取C库(glibc,如果有疑问)的调试符号,然后重试。

最新更新