Gcc 是否有x86指令来创建核心转储? 我想回答的一般性问题

Gcc 是否有x86指令来创建核心转储? 我想回答的一般性问题,gcc,x86,coredump,bus-error,Gcc,X86,Coredump,Bus Error,我有一些x86汇编代码,我正试图调试。我想得到一个堆芯转储,这样我可以检查正在发生的事情。是否有x86指令(或一组指令)将在程序中的给定点生成核心转储?如果出现错误,是否有方法组装程序集以使其核心转储 具体问题(此处解释内容) 我正在为下面的一个小lambda演算编写一个编译器。我现在正致力于实现闭包,我需要发布一个间接跳转。我正在尝试编译以下代码: (标签((f(代码(n)(+n1)))(app(闭包f)3)) 我的编译器生成以下内容: .text .p2align 4,

我有一些x86汇编代码,我正试图调试。我想得到一个堆芯转储,这样我可以检查正在发生的事情。是否有x86指令(或一组指令)将在程序中的给定点生成核心转储?如果出现错误,是否有方法组装程序集以使其核心转储

具体问题(此处解释内容) 我正在为下面的一个小lambda演算编写一个编译器。我现在正致力于实现闭包,我需要发布一个间接跳转。我正在尝试编译以下代码:

(标签((f(代码(n)(+n1)))(app(闭包f)3))
我的编译器生成以下内容:

     .text
     .p2align 4,,15
     .globl _scheme_entry
 _scheme_entry:
     movq %rdi, %r15
     jmp _definition_end38349
 _func_f38350:
     movq $4, %rax
     movq %rax, -16(%rsp)
     movq -8(%rsp), %rax
     addq -16(%rsp), %rax
     ret
 _definition_end38349:
     movq $12, %rax
     movq %rax, -24(%rsp)
     movq %rdi, -8(%rsp)
     leaq _func_f38350(%rip), %rax
     movq %rax, 0(%r15)
     movq %r15, %rax
     orq $6, %rax
     addq $8, %r15
     xorq $6, %rax
     movq %rax, %rdi
     addq $8, %rsp
     callq *%rdi
     subq $8, %rsp
     movq -8(%rsp), %rdi
     ret
我附带了一个用C编写的驱动程序文件,用于处理编译代码结果的格式和显示。以下为参考:

#包括
#包括
#包括
#定义fixnum_掩码3
#定义fixnum_标记0
#定义fixnum_移位2
#定义数据掩码7
#定义cons_标记1
#定义向量_标记2
#定义字符串_标记3
#定义符号标记5
#定义闭包标签6
#定义空_列表47
#定义字符标签15
#定义字符掩码255
#定义字符移位8
#定义bool_标签31
#定义布尔_掩码127
#定义bool_移位7
#定义堆大小8192
大小\u t方案\u项(大小\u t*堆);
无效格式值(大小值);
int main(int argc,字符**argv){
size_t*heap=malloc(heap_size);
size\u t val=方案项(堆);
格式_val(val);
返回0;
}
无效格式值(大小值){
if((val&bool_掩码)==bool_标记){
printf((val>>bool#u shift)?“#t”:“#f”);
}
else if((val&fixnum\u掩码)==fixnum\u标记){
printf(“%zu”,val>>fixnum\u shift);
}
else if((val和数据屏蔽)=关闭标记){
printf(“#”,val);
}
else if((val&fixnum\u mask)==cons\u标记){
瓦尔--;
大小车=*((大小车*)val);
大小cdr=*((大小)val+1);
printf(“(”);format_val(car);printf(“.”);format_val(cdr);printf(“)”;
}
else if(val==空列表){
printf(“()”);
}
/*else如果((val&char_掩码)==char_标记){*/
/*printf(“%c”,val>>字符移位)*/
/* } */
否则{
printf(“#”,val);
}
}
当我运行
gcc汇编文件.s driver.c
时,它在macOS上编译而没有任何问题。当我运行生成的
a.out
文件时,我得到以下错误:

[2]    84530 bus error  ./a.out
有没有办法得到一个内核转储,这样我就可以检查寄存器的值

奖励:如果你能看到我的装配有什么问题,我也不介意回答我曾尝试在代码中使用GDB,但每次我在
a.out
文件中尝试它时,它都会冻结

我在macOS上运行这个<代码>gcc——版本给出:

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 11.0.3 (clang-1103.0.32.62)
Target: x86_64-apple-darwin19.4.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
非常感谢。

您可以询问GCC:

$ cat tmp.c
void foo() { __builtin_trap(); }
$ gcc -O2 tmp.c
$ ./a.out 
Illegal instruction (core dumped)
$ gcc -O2 tmp.c -S -o-
        ...
        ud2

为什么不使用
lldb
单步执行并查看发生了什么?
SIGBUS
(总线错误)默认情况下会生成一个内核转储。如果您没有得到一个,那么您应该了解原因(可能是通过
ulimit
禁用的),而不是寻找另一条指令来尝试制作一个,由于同样的原因,这几乎肯定会失败。您可能会发现
ud2
指令很有用。请在调试器下运行您的代码,以捕获错误并就地检查所有内容。这是调试器真正擅长的一件事。您甚至可以在asm源代码中使用
int3
指令来设置软件断点。(这与调试器在调试器中设置断点时覆盖指令的第一个字节所用的指令相同。)+1表示
lldb
@Gene。我尝试过使用GDB,但当我尝试运行我的程序集时,它一直崩溃或挂起。LLDB工作起来很有魅力。谢谢大家的宝贵意见。我仍然没有成功地创建一个核心转储(见@yugr回答的评论)@JosephSible我需要如何处理
ulimit
以确保我得到一个核心转储?我注意到
ulimit-c
返回0;我把它设置为8192只是为了看看会发生什么,但我仍然没有得到一个核心转储。我遗漏了什么?我在mac上使用的调用是
gcc-fomit frame pointer-S tmp.c
,然后查看
tmp.S
。这是一个很好的技巧!非常感谢。奇怪的是,我没有看到核心转储文件。是否需要确保设置了
ulimit
或类似设置?@AshtonWiersdorf是的,很可能在您的系统上禁用了CoreDump/启用它们取决于您的系统(在Linux上,您需要
ulimit-c unlimited
,Mac请参阅)。