Skip to content

Enable stack traces on segfault in stage1 on linux #2355

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

Enable stack traces on segfault in stage1 on linux #2355

wants to merge 1 commit into from

Conversation

Rocknest
Copy link
Contributor

Proof of concept for linux x86_64 and i386.

Example stack trace in stage1 (bug #2309):

Received SIGSEGV at instruction 0x83b400 (addr=0x0)
Frame address: 0x7fffe0d615d0
Stack address: 0x7fffe0d61320

long-path/handler.zig:64:5: 0x90185a in segv_handler.handler.segvPanic (userland)
    @panic(""); // Segmentation fault
    ^
long-path/ir.cpp:7481:13: 0x83b3ff in ir_gen_node_raw (long-path/ir.cpp)
    switch (node->type) {
            ^
long-path/ir.cpp:7616:29: 0x833a5a in ir_gen_node_extra (long-path/ir.cpp)
    IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval);
                            ^
long-path/ir.cpp:7622:12: 0x846d46 in ir_gen_node (long-path/ir.cpp)
    return ir_gen_node_extra(irb, node, scope, LValNone);
           ^
====== etc =====
long-path/codegen.cpp:8347:9: 0x80d692 in gen_root_source (long-path/codegen.cpp)
long-path/codegen.cpp:9377:13: 0x80c2d9 in codegen_build_and_link (long-path/codegen.cpp)
long-path/main.cpp:1161:17: 0x7d7dc2 in main (long-path/main.cpp)
???:?:?: 0x7f50e3c61b96 in ??? (???)
???:?:?: 0x630e258d4c544154 in ??? (???)

Received SIGSEGV at instruction 0x9014dd (addr=0x0)
Frame address: 0x7fffe0d606e0
Stack address: 0x7fffe0d60640
Aborted (core dumped)

Due to bugs in stdlib there is a second segfault when it tries to unwind beyond the last stack frame.

@andrewrk
Copy link
Member

Nice proof of concept. I think this feature would be great to have enabled by default for some targets, such as linux. I do want the ability to opt out, however. I think a good way to do this will be for me to implement #2189 and then #1439. Then the startup code before main() can look at the root source file and see if the programmer wants to opt out, otherwise do this segfault handling to gain stack traces.

There will also be a way to explicitly install the segfault handler. That API could be used for example in the stage1 compiler, where libc is the one that calls main().

@emekoi
Copy link
Contributor

emekoi commented May 1, 2019

related: #1740 and windows implementation.

@shawnl
Copy link
Contributor

shawnl commented May 6, 2019

Also for SIGBUS. (unaligned memory faults).

@Rocknest
Copy link
Contributor Author

Rocknest commented May 9, 2019

@shawnl how do i even trigger SIGBUS? I tried casting u8 pointers to u64 pointers, but it works fine

@shawnl
Copy link
Contributor

shawnl commented May 9, 2019

@Rocknest I believe using an aligned SIMD load on unaligned memory will do it. (I've mainly dealt with it on old ARM chips)

@andrewrk andrewrk closed this in 1a1598c Jul 2, 2019
@andrewrk
Copy link
Member

andrewrk commented Jul 2, 2019

@Rocknest thanks for this, the above commit is inspired from your PR. I was able to avoid the tricks, and the implementation is in the standard library, on by default for all programs, with a way to opt out. The stage1 compiler opts in by manually calling std.debug.attachSegfaultHandler()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants