GDB不了解代码

时间:2015-02-26 15:40:57

标签: 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 = %d\n", 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.

问题在哪里?

Sample in wikipedia不正确?

3 个答案:

答案 0 :(得分:7)

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

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

还有:

 printf ("size of a = %d\n", foo_len (a));

错误,您无法合法打印size_t,就好像它是int一样;不是。您应该使用%zu打印size_t类型的值:

 printf("length of a = %zu\n", foo_len(a));

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

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

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