分段错误x86 <
我有一些由我自己的编译器创建的asm程序,当我想运行它们时,它们最终会出现分段错误。 所有指令都按照我想要的方式执行,但执行完成时会出现段错误。
当我尝试使用gdb来查看segfault时,它看起来总是出现在这一行:0x11ee90 <_dl_debug_state> push%ebp>
我甚至不知道这条线是什么,并且首先如何防止它导致段错误。
这里是这种程序的一个例子:
file "test_appel.c"
.text
.globl f
.type f, @function
f:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl 8(%ebp), %eax
pushl %eax
movl 12(%ebp), %eax
popl %ecx
imull %ecx, %eax
movl %eax, 16(%ebp)
movl 16(%ebp), %eax
leave
ret
.section .rodata
.LC0:
.string "appel à fonction pour la multiplicationn"
.LC1:
.string "resultat 2 * 3 = %dn"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $2, %eax
movl %eax, 8(%ebp)
movl $3, %eax
movl %eax, 12(%ebp)
movl 12(%ebp), %eax
movl %eax ,4(%esp)
movl 8(%ebp), %eax
movl %eax ,0(%esp)
call f
movl %eax, 4(%ebp)
movl 4(%esp), %eax
movl (%esp), %ecx
pushl %eax
pushl %ecx
movl $.LC0, %eax
movl %eax, (%esp)
call printf
popl %ecx
popl %eax
movl %eax, 4(%esp)
movl %ecx, (%esp)
movl 4(%esp),%eax
movl (%esp), %ecx
pushl %eax
pushl %ecx
movl 4(%ebp), %eax
movl %eax, %edx
movl %edx, 4(%esp)
movl $.LC1, (%esp)
call printf
popl %ecx
popl %eax
movl %eax, 4(%esp)
movl %ecx, (%esp)
leave
ret
segfault,它似乎总是出现在这一行: 0x11ee90 <_dl_debug_state> push %ebp>
这只意味着你已经损坏或耗尽了堆栈。
你的编译器确实看起来会发出破坏整个堆栈的代码。 特别是这些说明:
movl %eax, 8(%ebp)
...
movl %eax, 12(%ebp)
调用者(这是libc的一部分)中的本地变量损坏,所以在main
返回后看到崩溃并不令人惊讶。
您可能意图发出: movl %eax, -8(%ebp)
和movl %eax, -12(%ebp)
。
when i try to use gdb in order to look at the segfault, it appears that it always occurs at the line : 0x11ee90 <_dl_debug_state> push %ebp>
在函数调用基指针期间发生分段错误: %ebp
正被压入堆栈。 这看起来像是之前发生的堆栈损坏的反响。
您尚未共享来自GDB的完整堆栈跟踪以及地址空间信息。
在gdb当赛格故障做了disassemble
,以获得更多的信息,也是bt
把所有的函数调用来得到这个。
问题是你正在破坏退货指示。 如您所知,ebp + 4总是包含执行被调用函数后控件跳转的返回指令地址。 在你的情况下,你有这样的陈述:
movl %eax, 4(%ebp)
您正在将'f()'的返回值写入ebp + 4,这会破坏返回指令地址。 你删除这个陈述你不会得到分段错误。
链接地址: http://www.djcxy.com/p/43893.html