Skip to content
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

Stack overflow detection failure #7482

Open
straight-shoota opened this issue Feb 26, 2019 · 1 comment
Open

Stack overflow detection failure #7482

straight-shoota opened this issue Feb 26, 2019 · 1 comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. platform:linux-musl topic:stdlib:runtime

Comments

@straight-shoota
Copy link
Member

#6928 added a cool feature which detects whether an invalid memory access is actually a stack overflow error.

However, this detection does not yet seem to work correctly in all cases.

On alpine edge the spec for SO detection on main stack fails:

  1) seg fault detects stack overflow on the main stack
     Failure/Error: error.should contain("Stack overflow")

       Expected:   "Invalid memory access (signal 11) at address 0xffffc59b7e30\n[0xaab6d0310cb8] *CallStack::print_backtrace:Int32 +100\n[0xaab6d03034d0] __crystal_sigfault_handler +208\n[0xfff785619964] __setjmp +56\n[0xaab6d03444c0] *Pointer(Hash::Entry(String, NamedTuple(time: Time, location: Time::Location)) | Nil) +136\n[0xaab6d0303530] *foo:NoReturn +48\n[0xaab6d0308fdc] *foo:NoReturn +23260 (1522 times)\n[0xaab6d02f9130] __crystal_main +2072\n[0xaab6d034690c] *Crystal::main_user_code<Int32, Pointer(Pointer(UInt8))>:Nil +8\n[0xaab6d0346864] *Crystal::main<Int32, Pointer(Pointer(UInt8))>:Int32 +40\n[0xaab6d02ffedc] main +8\n[0xfff7855ee734] ???\n"
       to include: "Stack overflow"

     # spec/std/kernel_spec.cr:249

The spec for SO detection on fiber stack passes, though.

There was a similar failure reported for Ubuntu 14.04 which doesn't seem to have been fixed (#6928 (comment)).

If this can't be fixed right away, a short term play would be to simply disable the spec on affected platforms. They're not essential.

/cc @damaxwell

@straight-shoota straight-shoota added kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:stdlib:runtime labels Feb 26, 2019
@straight-shoota straight-shoota added this to the 0.28.0 milestone Feb 26, 2019
@bcardiff bcardiff removed this from the 0.28.0 milestone Mar 27, 2019
@HertzDevil
Copy link
Contributor

HertzDevil commented Sep 27, 2024

Stack overflow detection relies on the current thread's stack bounds. On Linux this is obtained using LibC.pthread_getattr_np and LibC.pthread_attr_getstack:

{% elsif flag?(:linux) %}
if LibC.pthread_getattr_np(@system_handle, out attr) == 0
LibC.pthread_attr_getstack(pointerof(attr), pointerof(address), out _)
end
ret = LibC.pthread_attr_destroy(pointerof(attr))
raise RuntimeError.from_os_error("pthread_attr_destroy", Errno.new(ret)) unless ret == 0

However, on musl-libc the internal stack size is always hardcoded to a very small default of 128 KiB, and pthread_getattr_np returns this value unmodified, presumably for the main thread as well. The result is that the main thread has an entirely incorrect @stack, as it respects ulimit -s, and that non-main threads are really that small, as we don't pass any attr to GC.pthread_create on thread creation. This is also mentioned on Ruby's bug tracker.

The stack trace itself is wrong as well, even though Exception::CallStack.print_backtrace works correctly as long as it is outside a signal handler. This appears to be an intentional won't-fix. If we need a meaningful stack trace inside a signal handler then we have to bypass _Unwind_Backtrace and mimic whatever a debugger like LLDB does.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. platform:linux-musl topic:stdlib:runtime
Projects
None yet
Development

No branches or pull requests

3 participants