【发布时间】:2021-07-11 12:36:07
【问题描述】:
我是使用 intel asm 64 位编码的新手,我正在尝试从 libc 重新编码 strdup,当我尝试在我的 c 主程序中对其进行测试时出现段错误,但我不明白为什么会出现此错误
这是我的 main.c:
#include "libasm.h"
int main(void)
{
printf(" _____________\n");
printf("// \\\\\n");
printf("|| ft_strdup ||\n");
printf("||_____________||\n");
char *str;
char *dup;
str = "test";
printf("segfault1\n");
dup = ft_strdup(str);
printf("segfault2\n");
printf("str: %s\n", dup);
free(dup);
return 0;
}
当我使用标志 -g -fsanitize 启动我的程序时,我在调用 ft_strdup 的行上遇到了这个段错误:
ASAN:DEADLYSIGNAL
=================================================================
==21414==ERROR: AddressSanitizer: SEGV on unknown address 0x55789815fa80 (pc 0x55789815fa80 bp 0x7ffe98c5e8a0 sp 0x7ffe98c5e3d8 T0)
==21414==The signal is caused by a READ memory access.
ASAN:DEADLYSIGNAL
AddressSanitizer: nested bug in the same thread, aborting.
gdb 回溯:
Program received signal SIGSEGV, Segmentation fault.
0x00005554f7a79140 in ?? ()
(gdb) backtrace
#0 0x00005554f7a79140 in ?? ()
#1 0x0000555555554fb2 in ft_strdup ()
#2 0x000055555555508a in ?? ()
#3 0x0000555555554e69 in main () at main.c:90
这里是指令0x0000555555554fb2:
(gdb) x/10i 0x0000555555554fb2
0x555555554fb2 <ft_strdup+18>: pop %rsi
0x555555554fb3 <ft_strdup+19>: mov %rax,%rdi
0x555555554fb6 <ft_strdup+22>: jmpq 0x555555554ef0 <ft_strcpy>
0x555555554fbb <ft_strdup+27>: nopl 0x0(%rax,%rax,1)
0x555555554fc0 <__libc_csu_init>: push %r15
0x555555554fc2 <__libc_csu_init+2>: push %r14
0x555555554fc4 <__libc_csu_init+4>: mov %rdx,%r15
0x555555554fc7 <__libc_csu_init+7>: push %r13
0x555555554fc9 <__libc_csu_init+9>: push %r12
0x555555554fcb <__libc_csu_init+11>: lea 0x200d9e(%rip),%r12 # 0x555555755d70
这是我的 ft_strdup 代码:
global ft_strdup
extern malloc
extern ft_strlen
extern ft_strcpy
ft_strdup:
push rdi
call ft_strlen
add rax, 1
mov rdi, rax
call malloc
pop rsi
mov rdi, rax
jmp ft_strcpy
这是我的 ft_strcpy 代码:
global ft_strcpy
ft_strcpy:
xor rax, rax
loop:
cmp byte [rsi + rax], 0
jz return
mov dl, [rsi + rax]
mov [rdi + rax], dl
inc rax
jmp loop
return:
mov byte [rdi + rax], 0
mov rax, rdi
ret
还有我的 ft_strlen 代码:
global ft_strlen
ft_strlen:
xor rcx, rcx
count:
cmp byte [rdi], 0
je ret;
inc rdi
inc rcx
jmp count
ret :
mov rax, rcx
ret
如果有人可以就可能导致此段错误的原因给我一些指示,那真的会对我有所帮助!
【问题讨论】:
-
您是否使用调试器查看异常发生的位置?
-
另外,虽然我不知道这是否会导致问题,但您似乎没有在函数调用时保持 16 字节堆栈对齐。
-
你所有的
ft函数都是用汇编写的吗?其他人是否按预期工作? -
提供minimal reproducible example 以及使用的命令。如果错误确实与调用有关,则意味着您以某种方式将
ft_strdup的地址弄错了。 -
@AmmarFaizi:
555555554fb2处的代码是call malloc的返回地址。这不是很有帮助;看到call指令本身的机器代码会使诊断段错误更有可能(即 rel32 由于重定位溢出而得到垃圾),所以dis ft_strdup会更有用。当然,将Symbol 'malloc' causes overflow in R_X86_64_PC32 relocation错误消息作为minimal reproducible example 的一部分包含在问题中会为大家节省很多时间。
标签: c assembly segmentation-fault x86-64