59 Commits

Author SHA1 Message Date
Alex Rønne Petersen
8263f55ab2
std.debug: add s390x-linux unwind support 2025-10-03 03:29:20 +02:00
Alex Rønne Petersen
97de46dc16
std.debug: add riscv32-linux and riscv64-linux unwind support 2025-10-01 23:47:47 +02:00
Alex Rønne Petersen
8520e9312e
std.debug: add loongarch64-linux unwind support 2025-10-01 23:47:47 +02:00
mlugg
1120546f72
std.debug.SelfInfo: remove shared logic
There were only a few dozen lines of common logic, and they frankly
introduced more complexity than they eliminated. Instead, let's accept
that the implementations of `SelfInfo` are all pretty different and want
to track different state. This probably fixes some synchronization and
memory bugs by simplifying a bunch of stuff. It also improves the DWARF
unwind cache, making it around twice as fast in a debug build with the
self-hosted x86_64 backend, because we no longer have to redundantly go
through the hashmap lookup logic to find the module. Unwinding on
Windows will also see a slight performance boost from this change,
because `RtlVirtualUnwind` does not need to know the module whatsoever,
so the old `SelfInfo` implementation was doing redundant work. Lastly,
this makes it even easier to implement `SelfInfo` on freestanding
targets; there is no longer a need to emulate a real module system,
since the user controls the whole implementation!

There are various other small refactors here in the `SelfInfo`
implementations as well as in the DWARF unwinding logic. This change
turned out to make a lot of stuff simpler!
2025-09-30 14:18:26 +01:00
mlugg
156cd8f678
std.debug: significantly speed up capturing stack traces
By my estimation, these changes speed up DWARF unwinding when using the
self-hosted x86_64 backend by around 7x. There are two very significant
enhancements: we no longer iterate frames which don't fit in the stack
trace buffer, and we cache register rules (in a fixed buffer) to avoid
re-parsing and evaluating CFI instructions in most cases. Alongside this
are a bunch of smaller enhancements, such as pre-caching the result of
evaluating the CIE's initial instructions, avoiding re-parsing of CIEs,
and big simplifications to the `Dwarf.Unwind.VirtualMachine` logic.
2025-09-30 13:44:56 +01:00
mlugg
099a950410
std.debug.SelfInfo: thread safety
This has been a TODO for ages, but in the past it didn't really matter
because stack traces are typically printed to stderr for which a mutex
is held so in practice there was a mutex guarding usage of `SelfInfo`.

However, now that `SelfInfo` is also used for simply capturing traces,
thread safety is needed. Instead of just a single mutex, though, there
are a couple of different mutexes involved; this helps make critical
sections smaller, particularly when unwinding the stack as `unwindFrame`
doesn't typically need to hold any lock at all.
2025-09-30 13:44:55 +01:00
mlugg
a18fd41064
std: rework/remove ucontext_t
Our usage of `ucontext_t` in the standard library was kind of
problematic. We unnecessarily mimiced libc-specific structures, and our
`getcontext` implementation was overkill for our use case of stack
tracing.

This commit introduces a new namespace, `std.debug.cpu_context`, which
contains "context" types for various architectures (currently x86,
x86_64, ARM, and AARCH64) containing the general-purpose CPU registers;
the ones needed in practice for stack unwinding. Each implementation has
a function `current` which populates the structure using inline
assembly. The structure is user-overrideable, though that should only be
necessary if the standard library does not have an implementation for
the *architecture*: that is to say, none of this is OS-dependent.

Of course, in POSIX signal handlers, we get a `ucontext_t` from the
kernel. The function `std.debug.cpu_context.fromPosixSignalContext`
converts this to a `std.debug.cpu_context.Native` with a big ol' target
switch.

This functionality is not exposed from `std.c` or `std.posix`, and
neither are `ucontext_t`, `mcontext_t`, or `getcontext`. The rationale
is that these types and functions do not conform to a specific ABI, and
in fact tend to get updated over time based on CPU features and
extensions; in addition, different libcs use different structures which
are "partially compatible" with the kernel structure. Overall, it's a
mess, but all we need is the kernel context, so we can just define a
kernel-compatible structure as long as we don't claim C compatibility by
putting it in `std.c` or `std.posix`.

This change resulted in a few nice `std.debug` simplifications, but
nothing too noteworthy. However, the main benefit of this change is that
DWARF unwinding---sometimes necessary for collecting stack traces
reliably---now requires far less target-specific integration.

Also fix a bug I noticed in `PageAllocator` (I found this due to a bug
in my distro's QEMU distribution; thanks, broken QEMU patch!) and I
think a couple of minor bugs in `std.debug`.

Resolves: #23801
Resolves: #23802
2025-09-30 13:44:54 +01:00
mlugg
cedd9de64f
std.debug.Dwarf: fix names of inlined functions 2025-09-30 13:44:53 +01:00
mlugg
1123741fd5
Dwarf: use 'gpa' terminology 2025-09-30 13:44:52 +01:00
mlugg
c1a30bd0d8
std: replace debug.Dwarf.ElfModule with debug.ElfFile
This abstraction isn't really tied to DWARF at all! Really, we're just
loading some information from an ELF file which is useful for debugging.
That *includes* DWARF, but it also includes other information. For
instance, the other change here:

Now, if DWARF information is missing, `debug.SelfInfo.ElfModule` will
name symbols by finding a matching symtab entry. We actually already do
this on Mach-O, so it makes obvious sense to do the same on ELF! This
change is what motivated the restructuring to begin with.

The symtab work is derived from #22077.

Co-authored-by: geemili <opensource@geemili.xyz>
2025-09-30 13:44:52 +01:00
mlugg
1392a7af17
std.debug: unwinding on Windows
...using `RtlVirtualUnwind` on x86_64 and aarch64, and
`RtaCaptureStackBackTrace` on x86.
2025-09-30 13:44:52 +01:00
mlugg
ac4d633ed6
std: fix debug.Info and debug.Coverage 2025-09-30 13:44:52 +01:00
mlugg
5709369d05
std.debug: improve the APIs and stuff 2025-09-30 13:44:51 +01:00
mlugg
d4f710791f
tweaks 2025-09-30 13:44:51 +01:00
mlugg
c895aa7a35
std.debug.SelfInfo: concrete error sets
The downside of this commit is that more precise errors are no longer
propagated up. However, these errors were pretty useless in isolation
due to them having no context; and regardless, we intentionally swallow
most of them in `std.debug` anyway. Therefore, this is better in
practice, because it allows `std.debug` to give slightly more useful
warnings when handling errors. This commit does that for unwind errors,
for instance, which differentiate between the unwind info being corrupt
vs missing vs inaccessible vs unsupported.

A better solution would be to also include more detailed information via
the diagnostics pattern, but this commit is an incremental improvement.
2025-09-30 13:44:50 +01:00
mlugg
1397b95143
std.debug.Dwarf: eliminate host pointer size dependency 2025-09-30 13:44:50 +01:00
mlugg
8fdcdb8c69
the world if Dwarf.ElfModule was like REALLY good: 2025-09-30 13:44:49 +01:00
mlugg
84b65860cf
the world if ElfModule didn't suck: 2025-09-30 13:44:49 +01:00
mlugg
55a7affea4
me when i did a thing 2025-09-30 13:44:49 +01:00
mlugg
fb88dab4c9
more still 2025-09-30 13:44:49 +01:00
mlugg
ed6ed62c42
more stuff 2025-09-30 13:44:49 +01:00
mlugg
b750e7cf9e
change one million things 2025-09-30 13:44:49 +01:00
Jacob Young
b706949736
debug: refactor stack frame capturing 2025-09-30 13:44:48 +01:00
Andrew Kelley
12686d9b7d delete std.debug.FixedBufferReader
now that std.Io.Reader has sufficient debug performance
2025-08-25 04:05:37 -07:00
Andrew Kelley
d00cc10086 std.debug: delete MemoryAccessor
This API is based around the unsound idea that a process can perform
checked virtual memory loads to prevent crashing. This depends on
OS-specific APIs that may be unavailable, disabled, or impossible due to
virtualization.

It also makes collecting stack traces ridiculously slow, which is a
problem for users of DebugAllocator - in other words, everybody, all the
time. It also makes strace go from being superbly clean to being awful.
2025-08-23 13:48:52 -07:00
Andrew Kelley
30b41dc510 std.compress.zstd.Decompress fixes
* std.Io.Reader: appendRemaining no longer supports alignment and has
  different rules about how exceeding limit. Fixed bug where it would
  return success instead of error.StreamTooLong like it was supposed to.

* std.Io.Reader: simplify appendRemaining and appendRemainingUnlimited
  to be implemented based on std.Io.Writer.Allocating

* std.Io.Writer: introduce unreachableRebase

* std.Io.Writer: remove minimum_unused_capacity from Allocating. maybe
  that flexibility could have been handy, but let's see if anyone
  actually needs it. The field is redundant with the superlinear growth
  of ArrayList capacity.

* std.Io.Writer: growingRebase also ensures total capacity on the
  preserve parameter, making it no longer necessary to do
  ensureTotalCapacity at the usage site of decompression streams.

* std.compress.flate.Decompress: fix rebase not taking into account seek

* std.compress.zstd.Decompress: split into "direct" and "indirect" usage
  patterns depending on whether a buffer is provided to init, matching
  how flate works. Remove some overzealous asserts that prevented buffer
  expansion from within rebase implementation.

* std.zig: fix readSourceFileToAlloc returning an overaligned slice
  which was difficult to free correctly.

fixes #24608
2025-08-15 10:44:35 -07:00
Andrew Kelley
749f10af49 std.ArrayList: make unmanaged the default 2025-08-11 15:52:49 -07:00
Andrew Kelley
2024abda6a std.debug.Dwarf: work around API deficiency
need to supply a big enough buffer when working with decompression
2025-07-31 22:10:11 -07:00
Andrew Kelley
83513ade35 std.compress: rework flate to new I/O API 2025-07-31 22:10:11 -07:00
Andrew Kelley
0e37ff0d59 std.fmt: breaking API changes
added adapter to AnyWriter and GenericWriter to help bridge the gap
between old and new API

make std.testing.expectFmt work at compile-time

std.fmt no longer has a dependency on std.unicode. Formatted printing
was never properly unicode-aware. Now it no longer pretends to be.

Breakage/deprecations:
* std.fs.File.reader -> std.fs.File.deprecatedReader
* std.fs.File.writer -> std.fs.File.deprecatedWriter
* std.io.GenericReader -> std.io.Reader
* std.io.GenericWriter -> std.io.Writer
* std.io.AnyReader -> std.io.Reader
* std.io.AnyWriter -> std.io.Writer
* std.fmt.format -> std.fmt.deprecatedFormat
* std.fmt.fmtSliceEscapeLower -> std.ascii.hexEscape
* std.fmt.fmtSliceEscapeUpper -> std.ascii.hexEscape
* std.fmt.fmtSliceHexLower -> {x}
* std.fmt.fmtSliceHexUpper -> {X}
* std.fmt.fmtIntSizeDec -> {B}
* std.fmt.fmtIntSizeBin -> {Bi}
* std.fmt.fmtDuration -> {D}
* std.fmt.fmtDurationSigned -> {D}
* {} -> {f} when there is a format method
* format method signature
  - anytype -> *std.io.Writer
  - inferred error set -> error{WriteFailed}
  - options -> (deleted)
* std.fmt.Formatted
  - now takes context type explicitly
  - no fmt string
2025-07-07 22:43:51 -07:00
Jacob Young
4adb7eca6a debug: correctly detect missing entries in .eh_frame_hdr 2025-05-17 02:08:41 -04:00
Alec Fessler
1cc388d526 stdlib: handle EEXIST in mmap with FIXED_NOREPLACE. Fixes #21475 2025-02-24 04:36:14 -05:00
Andrew Kelley
284de7d957 adjust runtime page size APIs
* fix merge conflicts
* rename the declarations
* reword documentation
* extract FixedBufferAllocator to separate file
* take advantage of locals
* remove the assertion about max alignment in Allocator API, leaving it
  Allocator implementation defined
* fix non-inline function call in start logic

The GeneralPurposeAllocator implementation is totally broken because it
uses global state but I didn't address that in this commit.
2025-02-06 14:23:23 -08:00
Archbirdplus
439667be04 runtime page size detection
heap.zig: define new default page sizes
heap.zig: add min/max_page_size and their options
lib/std/c: add miscellaneous declarations
heap.zig: add pageSize() and its options
switch to new page sizes, especially in GPA/stdlib
mem.zig: remove page_size
2025-02-06 14:23:23 -08:00
Alex Rønne Petersen
180db2bf23
std.debug: Fall back to .eh_frame/.debug_frame if .eh_frame_hdr is incomplete.
When using the self-hosted backends, especially in incremental mode, the
.eh_frame_hdr section may be incomplete, so we can't treat it as authoritative.

Instead, if we started out intending to use .eh_frame_hdr but find that it's
incomplete, load .eh_frame/.debug_frame on demand and use that info going
forward.
2025-01-23 23:22:38 +00:00
Jay Petacat
812557bfde std: Restore conventional compareFn behavior for binarySearch
PR #20927 made some improvements to the `binarySearch` API, but one
change I found surprising was the relationship between the left-hand and
right-hand parameters of `compareFn` was inverted. This is different
from how comparison functions typically behave, both in other parts of
Zig (e.g. `std.math.order`) and in other languages (e.g. C's `bsearch`).
Unless a strong reason can be identified and documented for doing
otherwise, I think it'll be better to stick with convention.

While writing this patch and changing things back to the way they were,
the predicates of `lowerBound` and `upperBound` seemed to be the only
areas that benefited from the inversion. I don't think that benefit is
worth the cost, personally. Calling `Order.invert()` in the predicates
accomplishes the same goal.
2024-09-16 14:04:18 -07:00
Linus Groh
8588964972 Replace deprecated default initializations with decl literals 2024-09-12 16:01:23 +01:00
Jacob Young
6a21875ddb
Merge pull request #21230 from jacobly0/stack-trace
Dwarf: fix self-hosted stack traces
2024-08-28 17:39:35 -04:00
Jacob Young
12275cf4b9 Dwarf: fix parsing self-hosted debug info for stack traces 2024-08-28 06:45:17 -04:00
mlugg
0fe3fd01dd
std: update std.builtin.Type fields to follow naming conventions
The compiler actually doesn't need any functional changes for this: Sema
does reification based on the tag indices of `std.builtin.Type` already!
So, no zig1.wasm update is necessary.

This change is necessary to disallow name clashes between fields and
decls on a type, which is a prerequisite of #9938.
2024-08-28 08:39:59 +01:00
Ian Johnson
0a70455095 Fix handling of empty XDG environment variables
Closes #21132

According to the XDG Base Directory specification
(https://specifications.freedesktop.org/basedir-spec/latest/#variables),
empty values for these environment variables should be treated the same
as if they are unset. Specifically, for the instances changed in this
commit,

> $XDG_DATA_HOME defines the base directory relative to which
> user-specific data files should be stored. If $XDG_DATA_HOME is either
> not set **or empty**, a default equal to $HOME/.local/share should be
> used.

and

> $XDG_CACHE_HOME defines the base directory relative to which
> user-specific non-essential data files should be stored. If
> $XDG_CACHE_HOME is either not set **or empty**, a default equal to
> $HOME/.cache should be used.

(emphasis mine)

In addition to the case mentioned in the linked issue, all other uses of
XDG environment variables were corrected.
2024-08-19 23:30:14 -07:00
Andrew Kelley
022bca9b06 std.debug.Dwarf: better source location information
Two fixes here:

Sort by addresses after generating the line table. Debug information in
the wild is not sorted and the rest of the implementation requires this
data to be sorted.

Handle DW.LNE.end_sequence correctly. When I originally wrote this code,
I misunderstood what this opcode was supposed to do. Now I understand
that it marks the *end* of an address range, meaning the current address
does *not* map to the current line information.

This fixes source location information for a big chunk of ReleaseSafe
code.
2024-08-13 18:04:23 -07:00
Andrew Kelley
b5398180d6 std.debug.Coverage.resolveAddressesDwarf: fix broken logic
The implementation assumed that compilation units did not overlap, which
is not the case. The new implementation uses .debug_ranges to iterate
over the requested PCs.

This partially resolves #20990. The dump-cov tool is fixed but the same
fix needs to be applied to `std.Build.Fuzz.WebServer` (sorting the PC
list before passing it to be resolved by debug info).

I am observing LLVM emit multiple 8-bit counters for the same PC
addresses when enabling `-fsanitize-coverage=inline-8bit-counters`. This
seems like a bug in LLVM. I can't fathom why that would be desireable.
2024-08-13 15:02:53 -07:00
Xavier Bouchoux
cbdf9bf5ee std.debug.Dwarf: try to load the debuginfo from the debuginfod cache.
The previous mecanism for linux distributions to delivers debug info into `/usr/lib/debug` no longer seems in use.
the current mecanism often is using `debuginfod` (https://sourceware.org/elfutils/Debuginfod.html)

This commit only tries to load already available debuginfo but does not try to make any download requests.
the user can manually run `debuginfod-find debuginfo PATH` to populate the cache.
2024-08-08 07:28:59 +02:00
Xavier Bouchoux
7e966de45e std.debug.Dwarf: fix loading external debuginfo in the ".debuglink" case.
- look up the debuglink file in the directory of the executable file (instead of the cwd)
 - fix parsing of debuglink section (the 4-byte alignement is within the file, unrelated to the in-memory address)
2024-08-08 07:15:00 +02:00
Andrew Kelley
40edd11516 std.debug: fix compile errors on windows and macos 2024-08-07 00:48:32 -07:00
Andrew Kelley
8dae629c4f update branch for latest std.sort changes 2024-08-07 00:48:32 -07:00
Andrew Kelley
53aa9d75a9 std.debug.Info.resolveSourceLocations: O(N) implementation 2024-08-07 00:48:32 -07:00
Andrew Kelley
c2ab4614b6 std.Debug.Info: remove std.Progress integration
it's too fast to need it now
2024-08-07 00:48:32 -07:00
Andrew Kelley
1792258dc8 std.debug.Dwarf: precompute .debug_line table
yields a 60x speedup for resolveSourceLocations in debug builds
2024-08-07 00:48:32 -07:00