2011-06-11 155 views
0

我分析这个核心转储GDB:地址范围映射

Program received signal SIGABRT, Aborted. 
    0xb7fff424 in __kernel_vsyscall() 
    (gdb) where 
    #0 0xb7fff424 in __kernel_vsyscall() 
    #1 0x0050cd71 in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 
    #2 0x0050e64a in abort() at abort.c:92 
    #3 0x08083b3b in ??() 
    #4 0x08095461 in ??() 
    #5 0x0808bdea in ??() 
    #6 0x0808c4e2 in ??() 
    #7 0x080b683b in ??() 
    #8 0x0805d845 in ??() 
    #9 0x08083eb6 in ??() 
    #10 0x08061402 in ??() 
    #11 0x004f8cc6 in __libc_start_main (main=0x805f390, argc=15, ubp_av=0xbfffef64, init=0x825e220, fini=0x825e210, 
     rtld_fini=0x4cb220 <_dl_fini>, stack_end=0xbfffef5c) at libc-start.c:226 
    #12 0x0804e5d1 in ??() 

我无法知道哪些功能??地图,或例如#10 0x08061402 in ??() 跌倒在地址范围...

请帮我调试一下。

回答

2

你的程序有没有调试符号。用-g重新编译它。确保你还没有剥离你的可执行文件,例如通过将-s传递给链接器。

+0

的标记的字段??不是从我已经用-g编译的程序:这些符号来形成共享库///哪一个?我想知道 ??以便我可以安装debuginfo – KernelMonk 2011-06-11 15:58:54

+0

@ user794080:然后您的程序使用的库之一缺少其调试符号。 – 2011-06-11 16:05:06

+0

@user:不,它们来自您的程序。 – ninjalj 2011-06-11 16:10:25

0

要知道库映射到应用程序,记录你的程序的PID,在gdb停止和其他控制台运行

cat /proc/$pid/maps 

wher $ pid是停止进程的PID。地图文件的格式在http://linux.die.net/man/5/proc描述 - 从开始“的/ proc/[数] /映射 一个包含当前映射存储器区域和它们的访问权限的文件”。

另外,如果您的操作系统不使用ASLR(地址空间布局随机化),或者是你的程序禁用,您可以使用

ldd ./program 

列出链接库和他们的记忆范围。但是,如果ASLR打开,您将无法获得真实的内存映射范围信息,因为每次运行程序时它都会发生变化。但即使如此,你会知道,动态链接了哪些库并为它们安装了调试信息。

+1

0x08xxx是可执行文件。 0x004xxx是库。我瘦OP没有运行exec-shield或PAX。 – ninjalj 2011-06-11 16:12:16

+0

它也可以是一个静态库。 – osgx 2011-06-11 16:14:19

+0

啊,是的,虽然我不希望'__libc_start_main'直接调用它。 – ninjalj 2011-06-11 16:15:16

2

即使@ user794080没有这么说,看来非常有可能,他的计划是32位Linux可执行文件。

有从主可执行符号两个可能的原因(我能想到的)(在该范围内的堆栈跟踪的所有符号[0x08040000,0x08100000)来自主可执行)没有露面。

  1. 主要的可执行文件实际上已经被剥夺了(这是一样的 ninjalj的答案),并经常当“-S”传递到连接器,也许在不经意间发生了。
  2. 可执行文件已经被编译为一个新的(er)GCC,但正在被一个旧的(er)GDB调试,该GDB扼杀了一些较新的矮结构(应该有GDB的警告)。
0

堆栈可能已损坏。 “??”例如,如果堆栈上的返回地址被缓冲区溢出覆盖,就会发生。