-
-
Notifications
You must be signed in to change notification settings - Fork 3k
std.debug
: greatly expand target support for segfault handling/unwinding, and remove public ucontext_t
completely
#25516
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
Conversation
std.debug
: greatly expand target support for segfault handling/unwinding, and remove public ucontext_t
completely
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also LGTM. I really like the addition of more reference links :)
}, | ||
|
||
.illumos => &.{ | ||
.x86, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Illumos and Solaris haven't supported x86 for a while now. You can run old binaries but it's discouraged to create new ones.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know Solaris hasn't, but illumos seems to still support userspace 32-bit applications? http://www.tribblix.org/32bit.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It only matters how you define can_unwind
:
- Does this arch-os-abi combo support unwinding?
- Does the Zig compiler emit code for this combo?
If 2 doesn't matter then you may as well add x86 to Solaris as well. It seems like it doesn't since sparc64-solaris
isn't there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sparc64-solaris
is just a to-do along with sparc64-linux
and others; I'll do a later pull request that adds full SPARC unwinding to all of std.debug
(unless @mlugg beats me to it?).
In general, I'm going off test/llvm_targets.zig
for what targets are relevant here. That file in turn boils down to which targets are still supported by the developers/vendor of the OS. If a target is missing here, it's probably because it's missing in test/llvm_targets.zig
, while a @compileError
represents work to be done.
That said, I'm not sure I entirely understand point 2; the Zig compiler should in theory be able to emit code for x86-solaris
, sparc-solaris
, sparc64-solaris
, etc. It's just that if a target is effectively dead and no one cares about it, we're not going to bother maintaining code paths for it.
I made a couple of decisions for this based on the fact that we don't expose the signal_ucontext_t type outside of the file: * Adding all the floating point and vector state to every ucontext_t and mcontext_t variant was way, way too much work, especially when we don't even use the stuff. So I deleted all that and kept only the bare minimum needed to reach into general-purpose registers. * There is no particularly compelling reason to stick to the naming and struct nesting used in the system headers. So we can actually unify the access patterns for almost all of these variants by taking some liberties here; as a result, fromPosixSignalContext() is now much nicer to read and extend.
This type is useful for two things: * Doing non-local control flow with ucontext.h functions. * Inspecting machine state in a signal handler. The first use case is not one we support; we no longer expose bindings to those functions in the standard library. They're also deprecated in POSIX and, as a result, not available in musl. The second use case is valid, but is very poorly served by the standard library. As evidenced by my changes to std.debug.cpu_context.signal_context_t, users will be better served rolling their own ucontext_t and especially mcontext_t types which fit their specific situation. Further, these types tend to evolve frequently as architectures evolve, and the standard library has not done a good job keeping up, or even providing them for all supported targets.
Added some missing |
Codeberg: https://codeberg.org/ziglang/zig/pulls/3
#25227 laid the groundwork for me to finally do some porting and other improvements in
std.debug
that I'd been meaning to do for ages. Thanks @mlugg!Greatly expanded target support for segfault handling/unwinding
This PR combined with
std.debug
Refactor #25227std.debug
: LoongArch and RISC-V unwind support + some minor cleanups #25437std.debug
: adds390x-linux
unwind support #25443std.debug
: fix FP-based unwinding onpowerpc64
#25450std.debug
: consider FP-based unwinding on hexagon and powerpc safe #25454std.debug
: add unwind support forhexagon-linux
#25480std.debug
: MIPS and PowerPC unwind support + some other stuff #25493std.debug
: prefer FP unwinding on targets where it is ideal #25494std.debug
: be more resilient in the face of unsupported registers #25496std.debug.Dwarf.SelfUnwinder
: assume same-value rule by default for all columns #25523results in us having greatly expanded target coverage for segfault handling and stack traces in general. There's still #25422 which I plan to tackle after this, but on basically every other target that sees real use with Zig (and probably even a few that don't), we now have working stack traces on crashes and when using
DebugAllocator
.I made a couple of decisions for this based on the fact that we don't expose the
signal_ucontext_t
type outside ofstd.debug.cpu_context
:ucontext_t
andmcontext_t
variant was way, way too much work, especially when we don't even use the stuff. So I deleted all that and kept only the bare minimum needed to reach into general-purpose registers.fromPosixSignalContext()
is now much nicer to read and extend.Removal of
ucontext_t
and related types/functionsThis type is useful for two things:
ucontext.h
functions.The first use case is not one we support; we no longer expose bindings to those functions in the standard library. They're also deprecated in POSIX and, as a result, not available in musl.
The second use case is valid, but is very poorly served by the standard library. As evidenced by my changes to
std.debug.cpu_context.signal_context_t
, users will be better served rolling their ownucontext_t
and especiallymcontext_t
types which fit their specific situation. Further, these types tend to evolve frequently as architectures evolve, and the standard library has not done a good job keeping up, or even providing them for all supported targets.