Skip to content

cmd/compile: consider using DWARF 5 #26379

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
aclements opened this issue Jul 13, 2018 · 47 comments
Closed

cmd/compile: consider using DWARF 5 #26379

aclements opened this issue Jul 13, 2018 · 47 comments
Assignees
Labels
Debugging NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@aclements
Copy link
Member

DWARF 5 has several advantages over previous versions of DWARF. Notably,

  1. It supports position-independent representations, which significantly reduces the number of relocations in object files and hence the size of object files and the load on the linker. In the go binary, 49% of the 503,361 total relocations are in the DWARF.

  2. It supports much more compact location and range list formats. The location and range list sections are 6% of the 12MiB of the go binary, even when zlib compressed.

  3. It has an official language code for Go. :)

DWARF 5 is quite new, and I don't think the rest of the ecosystem is ready yet, but I wanted to get the idea floating. It is supported by the GNU and LLVM toolchains and some debuggers. Support was added in GCC 7.1 (May 2017) and GDB 8.0 (June 2017). It appears to be in the latest LLVM, which covers most of the Xcode tools, though I can't find when it was added.

It is currently not supported by LLDB or the macOS linker. We could potentially get around the macOS linker by leaving out the Go DWARF from the objects we pass to the system linker and then merging it in to the final binary (we already do a merge step). This is more feasible with DWARF5 because it's mostly position-independent, so we wouldn't need dsymutil to relocate it for us.

/cc @cherrymui @heschik @dr2chase @randall77 @ianlancetaylor

@gopherbot gopherbot added this to the Proposal milestone Jul 13, 2018
@heschi
Copy link
Contributor

heschi commented Jul 14, 2018

Strongly in favor of doing this the moment we think we can get away with it. I'm happy to do the work for location lists.

@bradfitz
Copy link
Contributor

Un-proposaling this per discussion with @ianlancetaylor.

@bradfitz bradfitz changed the title proposal: cmd/compile: consider using DWARF 5 cmd/compile: consider using DWARF 5 Jul 16, 2018
@bradfitz bradfitz removed the Proposal label Jul 16, 2018
@agnivade agnivade modified the milestones: Proposal, Unplanned Jul 17, 2018
@aarzilli
Copy link
Contributor

aarzilli commented Oct 11, 2018

For reference, the debug info for the linux_amd64/go1.11.1 version of cmd/compile is 15MB of which 8MB are in debug_loc and debug_ranges, specifically:

total size 20752567

section             compressed    uncompressed
.zdebug_abbrev             274 B         467 B
.zdebug_line            739610 B     1931456 B
.zdebug_frame           158093 B      559020 B
.zdebug_pubnames         38451 B      251078 B
.zdebug_pubtypes         45270 B      211390 B
.debug_gdb_scripts                        42 B
.zdebug_info           1257828 B     3694829 B
.zdebug_loc             989048 B     5914085 B
.zdebug_ranges          442419 B     2461408 B

Rewriting debug_loc and debug_ranges in the new format specified by DWARF 5 will reduce the size of debug_ranges to 774460 B (31% of DWARF 4 size) and of debug_loc to 2032960 B (34% of DWARF 4 size).

Edit: debug_ranges and debug_loc were accidentally swapped in the last sentence.

@dr2chase
Copy link
Contributor

Is compression still doing a better job at reducing binary size than DWARF 5, or can D5 also be compressed? I did just mostly finish a DWARF splitter for OSX that recreates the expected file in the expected place, and adds the expected UUID for matching the two files. I suspect I ought to be using a hash of the binary contents excluding debugging information, so that identical files will remain identical after UUIDs are added.

@aclements
Copy link
Member Author

The compression isn't actually part of the DWARF spec, so it's orthogonal to the DWARF version and can be used with DWARF 5.

@aarzilli, thanks for doing that experiment. Can you get the numbers for DWARF 5 if it's also zlib compressed?

@aarzilli
Copy link
Contributor

@aarzilli, thanks for doing that experiment. Can you get the numbers for DWARF 5 if it's also zlib compressed?

After compression the size is basically the same, 98% (of compressed DWARF4) for debug_ranges and 77% (of compressed DWARF4) for debug_loc. The compression time however is reduced by 40%.

@dr2chase
Copy link
Contributor

Is that compression time+space comparing current low-effort (higher speed) versus future low-effort? Sorry to be so picky, it's just that we've made mistakes here before.

@aarzilli
Copy link
Contributor

I'm comparing compression using zlib.BestSpeed for both, like the linker. Since measuring how much time it actually took inside the linker is hard I measured how much time it takes to recompress the compressed section.

Because I have send the whole section to the compressor and the linker doesn't, I get slightly better compression than the linker. But the difference is small (around 1%) and since I'm doing it for both DWARF 4 and DWARF 5 the result should be valid.

@ALTree ALTree added the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label Jul 22, 2020
@joeyjiaojg
Copy link

Parsed a DWARF5 linux kernel module, the below statement of index 0 is not nil. It returns the real file path.

<html>
<body>
<!--StartFragment-->

// Files returns the file name table of this compilation unit as of
--
  | // the current position in the line table. The file name table may be
  | // referenced from attributes in this compilation unit such as
  | // AttrDeclFile.
  | //
  **| // Entry 0 is always nil, since file index 0 represents "no file".**
  | //
  | // The file name table of a compilation unit is not fixed. Files
  | // returns the file table as of the current position in the line
  | // table. This may contain more entries than the file table at an
  | // earlier position in the line table, though existing entries never
  | // change.
  | func (r *LineReader) Files() []*LineFile {
  | return r.fileEntries
  | }

<!--EndFragment-->
</body>
</html>

@mdempsky
Copy link
Contributor

mdempsky commented Sep 1, 2023

FWIW, GCC 11.1 was released on April 27, 2021. From https://gcc.gnu.org/gcc-11/changes.html:

For targets that produce DWARF debugging information GCC now defaults to DWARF version 5 (with the exception of VxWorks and Darwin/Mac OS X which default to version 2 and AIX which defaults to version 4).

Also, Clang 14 was released on March 25, 2022. From https://releases.llvm.org/14.0.0/tools/clang/docs/ReleaseNotes.html#dwarf-support-in-clang:

The default DWARF version has increased from DWARFv4 to DWARFv5. You can opt back in to the old behavior with -gdwarf-4 or -fdebug-default-version=4. Some platforms (Darwin, Android, and SCE for instance) already opt out of this version bump as is suitable for the platform

@thanm
Copy link
Contributor

thanm commented Dec 13, 2024

Hi all, I'm working on a set of patches to switch the Go compiler/linker over to DWARF 5, just FYI.

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/633878 mentions this issue: cmdinternal/dwarf: add DW_LNCT and DW_UT constant definitions

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/633880 mentions this issue: cmd/internal/objabi: add new R_DWTXTADDR_* relocation types

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/635345 mentions this issue: cmd/compile,cmd/link: move to DWARF5-style range lists

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/635337 mentions this issue: cmd: initial compiler+linker support for DWARF5 .debug_addr

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/633879 mentions this issue: cmd/link, cmd/internal/dwarf: add DWARF5 line table support

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/633877 mentions this issue: internal/goexperiment: add a new experiment to gate DWARF version 5

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/634415 mentions this issue: cmd/internal/objabi,cmd/link/internal/sym: add SDWARFADDR symbol type

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/635836 mentions this issue: cmd/compile,cmd/link: move to DWARF5-style location lists

@thanm
Copy link
Contributor

thanm commented Mar 11, 2025

Update:

As reported by Alessandro, the binutils "objdump" command is complaining that the .debug_addr section being produced by the Go toolchain with GOEXPERIMENT=dwarf5 is malformed; I spent some time debugging objdump this morning after building a fresh copy from binutils tip, and I confirmed that this is indeed still the case. Here is an example:

$ go build himom.go
$ objdump --dwarf=addr himom > /dev/null
objdump: Warning: Corrupt .debug_addr section: expecting header size of 8 or 16, but found -14128 instead
$

Here's what's happening.

As currently implemented, the Go toolchain generates a single monolithic .debug_addr section entirely in the linker, as opposed to what C toolchains do, which is to have the compiler emit a .debug_frame section fragment for each translation unit and have them all glommed together by the linker when the final binary is written out.

The code binutils objdump is essentially mandating the C model, that is, it requires that there be a section header for each compilation unit (since this is what most C compilers do); it ignores the length field in the single .debug_addr header and instead for a given unit K, uses the DW_AT_addr_base value of unit K+1 as a proxy for the length of K's contributions. Code here, note the i+1:

https://github.com/bminor/binutils-gdb/blob/827f39f7e5d0c208275482cec979b9b5592c4aa8/binutils/dwarf.c#L7917

After it has finished printing the .debug_addr entries for unit K, it then requires that there be another section header immediately following, which it tries to validate (and fails, of course).

It is unfortunate that it works this way, since there is nothing in the DWARF standard that requires the "one header per compilation unit" model, and the hijacking or overloading of the DW_AT_addr_base value is not something recommended or talked about in the standard either as far as I know. The standard only says that DW_AT_addr_base gives the starting point for entries corresponding to CU K, it does not say anything about previous compilation units).

Also worth noting that the Go toolchain uses a similar monolithic section approach for .debug_frames as well, which objdump doesn't seem to mind.

I'll need to think about what to do about this.

@ianlancetaylor
Copy link
Contributor

The fix for the GNU binutils seems fairly easy. Should we just send them a patch?

@thanm
Copy link
Contributor

thanm commented Mar 11, 2025

The fix for the GNU binutils seems fairly easy. Should we just send them a patch?

I agree it's worth doing this. I don't think it should block moving to DWARF 5 for Go, however.

gopherbot pushed a commit that referenced this issue Mar 12, 2025
This patch enables the DWARF version 5 experiment by default for most
platforms that support DWARF. Note that MacOS is kept at version 4,
due to problems with CGO builds; the "dsymutil" tool from older
versions of Xcode (prior to V16) can't handle DWARF5. Similar we keep
DWARF 4 for GOOS=aix, where XCOFF doesn't appear to support the new
section subtypes in DWARF 5.

Updates #26379.

Change-Id: I5edd600c611f03ce8e11be3ca18c1e6686ac74ef
Reviewed-on: https://go-review.googlesource.com/c/go/+/637895
Reviewed-by: Cherry Mui <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: David Chase <[email protected]>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/656895 mentions this issue: internal/buildcfg: fix typo in DWARF 5 enabling code

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/656836 mentions this issue: runtime: increase GDB version testing requirement to 10 from 7.7

gopherbot pushed a commit that referenced this issue Mar 12, 2025
Fix a typo in the code that decides which GOOS values will support use
of DWARF 5 ("darwin" was not spelled correctly).

Updates #26379.

Change-Id: I3a7906d708550fcedc3a8e89d0444bf12b9143f1
Reviewed-on: https://go-review.googlesource.com/c/go/+/656895
Auto-Submit: Ian Lance Taylor <[email protected]>
Reviewed-by: Ian Lance Taylor <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: David Chase <[email protected]>
gopherbot pushed a commit that referenced this issue Mar 12, 2025
Bump the required version of GDB up to 10 from 7.7 in the runtime GDB
tests, so as to ensure that we have something that can handle DWARF 5
when running tests. In theory there is some DWARF 5 support on the
version 9 release branch, but we get "Dwarf Error: DW_FORM_addrx"
errors for some archs on builders where GDB 9.2 is installed.

Updates #26379.

Change-Id: I1b7b45f8e4dd1fafccf22f2dda0124458ecf7cba
Reviewed-on: https://go-review.googlesource.com/c/go/+/656836
Auto-Submit: Ian Lance Taylor <[email protected]>
Reviewed-by: David Chase <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: Ian Lance Taylor <[email protected]>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/657175 mentions this issue: cmd/internal/dwarf: fix bug in inlined func DIE range DWARF 5 info

gopherbot pushed a commit that referenced this issue Mar 12, 2025
This patch changes the strategy we use in the compiler for handling
range information for inlined subroutine bodies, fixing a bug in how
this was handled for DWARF 5.  The high and lo PC values being emitted
for DW_TAG_inlined_subroutine DIEs were incorrect, pointing to the
start of functions instead of the proper location. The fix in this
patch is to move to unconditionally using DW_AT_ranges for inlined
subroutines, even those with only a single range.

Background: prior to this point, if a given inlined function body had
a single contiguous range, we'd pick an abbrev entry for it with
explicit DW_AT_low_pc and DW_AT_high_pc attributes. If the extent of
the code for the inlined body was not contiguous (which can happen),
we'd select an abbrev that used a DW_AT_ranges attribute instead. This
strategy (preferring explicit hi/lo PC attrs for a single-range func)
made sense for DWARF 4, since in DWARF 4 the representation used in
the .debug_ranges section was especially heavyweight (lots of space,
lots of relocations), so having explicit hi/lo PC attrs was less
expensive.

With DWARF 5 range info is written to the .debug_rnglists section, and
the representation here is much more compact. Specifically, a single
hi/lo range can be represented using a base address in addrx format
(max of 4 bytes, but more likely 2 or 3) followed by start and
endpoints of the range in ULEB128 format. This combination is more
compact spacewise than the explicit hi/lo values, and has fewer
relocations (0 as opposed to 2).

Note: we should at some point consider applying this same strategy to
lexical scopes, since we can probably reap some of the same benefits
there as well.

Updates #26379.
Fixes #72821.

Change-Id: Ifb65ecc6221601bad2ca3939f9b69964c1fafc7c
Reviewed-on: https://go-review.googlesource.com/c/go/+/657175
Reviewed-by: Ian Lance Taylor <[email protected]>
Reviewed-by: Cherry Mui <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: Alessandro Arzilli <[email protected]>
@gopherbot
Copy link
Contributor

Change https://go.dev/cl/657177 mentions this issue: cmd/internal/dwarf: always use AT_ranges for scopes with DWARF 5

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/657176 mentions this issue: doc/next: add tentative DWARF 5 release note fragment

gopherbot pushed a commit that referenced this issue Mar 13, 2025
Add a small fragment describing the move to DWARF 5 for this release,
along with the name of the GOEXPERIMENT.

Updates #26379.

Change-Id: I3a30a71436133e2e0a5edf1ba0db84b9cc17cc5c
Reviewed-on: https://go-review.googlesource.com/c/go/+/657176
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: David Chase <[email protected]>
Reviewed-by: Ian Lance Taylor <[email protected]>
gopherbot pushed a commit that referenced this issue Mar 13, 2025
This patch extends the change in CL 657175 to apply the same abbrev
selection strategy to single-range lexical scopes that we're now using
for inlined routine bodies, when DWARF 5 is in effect. Ranges are more
compact and use fewer relocation than explicit hi/lo PC values, so we
might as well always use them.

Updates #26379.

Change-Id: Ieeaddf50e82acc4866010e29af32bcd1fb3b4f02
Reviewed-on: https://go-review.googlesource.com/c/go/+/657177
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: Ian Lance Taylor <[email protected]>
Reviewed-by: Cherry Mui <[email protected]>
@thanm
Copy link
Contributor

thanm commented Mar 13, 2025

Update: DWARF 5 is now enabled at tip (for non-darwin and non-aix platforms) 🎉🎉🎉. I have fixed a few bugs, but so far things look good.

@cherrymui
Copy link
Member

Hi @thanm , thank you for the great work! Is there anything we still need to do for this issue? Or we can close this? Thanks.

@thanm
Copy link
Contributor

thanm commented Apr 5, 2025

I think we can close the issue, thanks. I am still looking at issue #72810 which I think is some sort of book-keeping problem in the compiler, I hope to have a fix soon (I don't expect this to be a deal-breaker). Hopefully we can enable DWARF5 by default for darwin once the oldest supported xcode version includes the necessary support (e.g. V17).

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/663235 mentions this issue: cmd: fix DWARF gen bug with packages that use assembly

@thanm
Copy link
Contributor

thanm commented Apr 5, 2025

Closing out this issue since I now have a fix in flight for #72810.

@thanm thanm closed this as completed Apr 5, 2025
gopherbot pushed a commit that referenced this issue Apr 13, 2025
When the compiler builds a Go package with DWARF 5 generation enabled,
it emits relocations into various generated DWARF symbols (ex:
SDWARFFCN) that use the R_DWTXTADDR_* flavor of relocations. The
specific size of this relocation is selected based on the total number
of functions in the package -- if the package is tiny (just a couple
funcs) we can use R_DWTXTADDR_U1 relocs (which target just a byte); if
the package is larger we might need to use the 2-byte or 3-byte flavor
of this reloc.

Prior to this patch, the strategy used to pick the right relocation
size was flawed in that it didn't take into account packages with
assembly code. For example, if you have a package P with 200 funcs
written in Go source and 200 funcs written in assembly, you can't use
the R_DWTXTADDR_U1 reloc flavor for indirect text references since the
real function count for the package (asm + go) exceeds 255.

The new strategy (with this patch) is to have the compiler look at the
"symabis" file to determine the count of assembly functions. For the
assembler, rather than create additional plumbing to pass in the Go
source func count we just use an dummy (artificially high) function
count so as to select a relocation that will be large enough.

Fixes #72810.
Updates #26379.

Change-Id: I98d04f3c6aacca1dafe1f1610c99c77db290d1d8
Reviewed-on: https://go-review.googlesource.com/c/go/+/663235
Reviewed-by: Dmitri Shuralyov <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: David Chase <[email protected]>
ajwerner added a commit to DataDog/datadog-agent that referenced this issue May 23, 2025
This package abstracts object files for use in dyninst. It importantly
retains access to sections for use outside of just the *dwarf.Data construction
so that the same sections can be reused for location list parsing and other
operations not directly supported by debug/dwarf. It also wraps the abstractions
provided by delve's loclist package to make location lists easier to parse.

This layer can also in the future (if we deem it relevant) model the differences
between elf and mach-o (though that's possibly over-abstracting a bit).

There's some TODOs left for supporting dwarf 5 location lists that are coming
in the next Go release (see [0]).

[0]: golang/go#26379
ajwerner added a commit to DataDog/datadog-agent that referenced this issue May 28, 2025
This package abstracts object files for use in dyninst. It importantly
retains access to sections for use outside of just the *dwarf.Data construction
so that the same sections can be reused for location list parsing and other
operations not directly supported by debug/dwarf. It also wraps the abstractions
provided by delve's loclist package to make location lists easier to parse.

This layer can also in the future (if we deem it relevant) model the differences
between elf and mach-o (though that's possibly over-abstracting a bit).

There's some TODOs left for supporting dwarf 5 location lists that are coming
in the next Go release (see [0]).

[0]: golang/go#26379
ajwerner added a commit to DataDog/datadog-agent that referenced this issue May 29, 2025
This package abstracts object files for use in dyninst. It importantly
retains access to sections for use outside of just the *dwarf.Data construction
so that the same sections can be reused for location list parsing and other
operations not directly supported by debug/dwarf. It also wraps the abstractions
provided by delve's loclist package to make location lists easier to parse.

This layer can also in the future (if we deem it relevant) model the differences
between elf and mach-o (though that's possibly over-abstracting a bit).

There's some TODOs left for supporting dwarf 5 location lists that are coming
in the next Go release (see [0]).

[0]: golang/go#26379
ajwerner added a commit to DataDog/datadog-agent that referenced this issue May 29, 2025
This package abstracts object files for use in dyninst. It importantly
retains access to sections for use outside of just the *dwarf.Data construction
so that the same sections can be reused for location list parsing and other
operations not directly supported by debug/dwarf. It also wraps the abstractions
provided by delve's loclist package to make location lists easier to parse.

This layer can also in the future (if we deem it relevant) model the differences
between elf and mach-o (though that's possibly over-abstracting a bit).

There's some TODOs left for supporting dwarf 5 location lists that are coming
in the next Go release (see [0]).

[0]: golang/go#26379
ajwerner added a commit to DataDog/datadog-agent that referenced this issue May 29, 2025
This package abstracts object files for use in dyninst. It importantly
retains access to sections for use outside of just the *dwarf.Data construction
so that the same sections can be reused for location list parsing and other
operations not directly supported by debug/dwarf. It also wraps the abstractions
provided by delve's loclist package to make location lists easier to parse.

This layer can also in the future (if we deem it relevant) model the differences
between elf and mach-o (though that's possibly over-abstracting a bit).

There's some TODOs left for supporting dwarf 5 location lists that are coming
in the next Go release (see [0]).

[0]: golang/go#26379
ajwerner added a commit to DataDog/datadog-agent that referenced this issue May 29, 2025
This package abstracts object files for use in dyninst. It importantly
retains access to sections for use outside of just the *dwarf.Data construction
so that the same sections can be reused for location list parsing and other
operations not directly supported by debug/dwarf. It also wraps the abstractions
provided by delve's loclist package to make location lists easier to parse.

This layer can also in the future (if we deem it relevant) model the differences
between elf and mach-o (though that's possibly over-abstracting a bit).

There's some TODOs left for supporting dwarf 5 location lists that are coming
in the next Go release (see [0]).

[0]: golang/go#26379
ajwerner added a commit to DataDog/datadog-agent that referenced this issue May 29, 2025
This package abstracts object files for use in dyninst. It importantly
retains access to sections for use outside of just the *dwarf.Data construction
so that the same sections can be reused for location list parsing and other
operations not directly supported by debug/dwarf. It also wraps the abstractions
provided by delve's loclist package to make location lists easier to parse.

This layer can also in the future (if we deem it relevant) model the differences
between elf and mach-o (though that's possibly over-abstracting a bit).

There's some TODOs left for supporting dwarf 5 location lists that are coming
in the next Go release (see [0]).

[0]: golang/go#26379
ajwerner added a commit to DataDog/datadog-agent that referenced this issue May 29, 2025
This package abstracts object files for use in dyninst. It importantly
retains access to sections for use outside of just the *dwarf.Data construction
so that the same sections can be reused for location list parsing and other
operations not directly supported by debug/dwarf. It also wraps the abstractions
provided by delve's loclist package to make location lists easier to parse.

This layer can also in the future (if we deem it relevant) model the differences
between elf and mach-o (though that's possibly over-abstracting a bit).

There's some TODOs left for supporting dwarf 5 location lists that are coming
in the next Go release (see [0]).

[0]: golang/go#26379

This commit introduces the package with a ridiculous mispelling to work around
gitignore rules.
ajwerner added a commit to DataDog/datadog-agent that referenced this issue May 29, 2025
This package abstracts object files for use in dyninst. It importantly
retains access to sections for use outside of just the *dwarf.Data construction
so that the same sections can be reused for location list parsing and other
operations not directly supported by debug/dwarf. It also wraps the abstractions
provided by delve's loclist package to make location lists easier to parse.

This layer can also in the future (if we deem it relevant) model the differences
between elf and mach-o (though that's possibly over-abstracting a bit).

There's some TODOs left for supporting dwarf 5 location lists that are coming
in the next Go release (see [0]).

[0]: golang/go#26379

This commit introduces the package with a ridiculous mispelling to work around
gitignore rules.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Debugging NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests