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

pkg/proc/gdbserial: optimize gdbwire backend #3715

Merged
merged 10 commits into from May 15, 2024

Conversation

derekparker
Copy link
Member

This change optimizes the gdbwire backend by reducing the number of
round trips we have to make to debugserver. It does this by using the
jstopinfo packet to only query threads which we know to have a stop
reason, and it also uses the registers returned by the 'T' packet
to avoid issuing a bunch of 'p' packets to get the register values.

Copy link
Member

@aarzilli aarzilli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you test these changes with rr? If not I will.

pkg/proc/gdbserial/gdbserver_conn.go Show resolved Hide resolved
pkg/proc/gdbserial/gdbserver_conn.go Show resolved Hide resolved
@derekparker
Copy link
Member Author

Did you test these changes with rr? If not I will.

There's some failures on the rr backend, I'm working to address those now.

@derekparker
Copy link
Member Author

derekparker commented Apr 30, 2024

I'm actually seeing failures already with RR on our latest tagged version with the latest RR:

RR failure
deparker on area51 at delve :  master [$]
❯ git co v1.22.1
Note: switching to 'v1.22.1'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 26799555 *: release version 1.22.1 (#3662)

deparker on area51 at delve :  HEAD (2679955) [$]
❯ rr --version
rr version 5.7.0

deparker on area51 at delve :  HEAD (2679955) [$]
❯ go test -count=1 -run TestReverseBreakpointCounts -v ./pkg/proc/gdbserial
=== RUN   TestReverseBreakpointCounts
    support.go:246: enabling recording for TestReverseBreakpointCounts
    rr_test.go:32: recording
    rr_test.go:37: replaying "/home/deparker/.local/share/rr/bpcountstest.3a506f46-0"
[FATAL src/ReplaySession.cc:1172:check_ticks_consistency()]
 (task 557388 (rec:557371) at time 5093)
 -> Assertion `ticks_now == trace_ticks' failed to hold. ticks mismatch for 'SYSCALL: clock_gettime'; expected 34035, got 34033
Tail of trace dump:
{
  real_time:426777.738414 global_time:5073, event:`SYSCALL: clock_gettime' (state:ENTERING_SYSCALL) tid:557371, ticks:33876
rax:0xffffffffffffffda rbx:0xc000048008 rcx:0xffffffffffffffff rdx:0xc00002bf38 rsi:0xc00002bf00 rdi:0x1 rbp:0xc00002bf28 rsp:0xc00002bef8 r8:0x0 r9:0x0 r10:0x0 r11:0x246 r12:0xc00002bf18 r13:0xc000049008 r14:0xc000006540 r15:0x3ffffffffffff rip:0x6ffff030 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xe4 fs_base:0xc000048098 gs_base:0x0
}
{
  real_time:426777.738435 global_time:5074, event:`SYSCALL: clock_gettime' (state:EXITING_SYSCALL) tid:557371, ticks:33876
rax:0x0 rbx:0xc000048008 rcx:0xffffffffffffffff rdx:0xc00002bf38 rsi:0xc00002bf00 rdi:0x1 rbp:0xc00002bf28 rsp:0xc00002bef8 r8:0x0 r9:0x0 r10:0x0 r11:0x246 r12:0xc00002bf18 r13:0xc000049008 r14:0xc000006540 r15:0x3ffffffffffff rip:0x6ffff030 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xe4 fs_base:0xc000048098 gs_base:0x0
  { tid:557371, addr:0xc00002bf00, length:0x10 }
}
{
  real_time:426777.738461 global_time:5075, event:`SYSCALL: clock_gettime' (state:ENTERING_SYSCALL) tid:557371, ticks:33919
rax:0xffffffffffffffda rbx:0xc000048008 rcx:0xffffffffffffffff rdx:0xc00002bed8 rsi:0xc00002bea0 rdi:0x1 rbp:0xc00002bec8 rsp:0xc00002be98 r8:0x0 r9:0x0 r10:0x0 r11:0x246 r12:0xc00002beb8 r13:0xc000049008 r14:0xc000006540 r15:0x3ffffffffffff rip:0x6ffff030 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xe4 fs_base:0xc000048098 gs_base:0x0
}
{
  real_time:426777.738482 global_time:5076, event:`SYSCALL: clock_gettime' (state:EXITING_SYSCALL) tid:557371, ticks:33919
rax:0x0 rbx:0xc000048008 rcx:0xffffffffffffffff rdx:0xc00002bed8 rsi:0xc00002bea0 rdi:0x1 rbp:0xc00002bec8 rsp:0xc00002be98 r8:0x0 r9:0x0 r10:0x0 r11:0x246 r12:0xc00002beb8 r13:0xc000049008 r14:0xc000006540 r15:0x3ffffffffffff rip:0x6ffff030 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xe4 fs_base:0xc000048098 gs_base:0x0
  { tid:557371, addr:0xc00002bea0, length:0x10 }
}
{
  real_time:426777.738506 global_time:5077, event:`SYSCALL: futex' (state:ENTERING_SYSCALL) tid:557371, ticks:33921
rax:0xffffffffffffffda rbx:0x0 rcx:0xffffffffffffffff rdx:0x0 rsi:0x80 rdi:0x547960 rbp:0xc00002bec8 rsp:0xc00002be80 r8:0x0 r9:0x0 r10:0xc00002beb8 r11:0x246 r12:0xc00002beb8 r13:0xc000049008 r14:0xc000006540 r15:0x3ffffffffffff rip:0x467aa3 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xca fs_base:0xc000048098 gs_base:0x0
}
{
  real_time:426777.743282 global_time:5078, event:`SYSCALL: epoll_pwait' (state:EXITING_SYSCALL) tid:557372, ticks:41319
rax:0x0 rbx:0x4 rcx:0xffffffffffffffff rdx:0x80 rsi:0xc000067774 rdi:0x4 rbp:0xc000067718 rsp:0xc0000676d0 r8:0x0 r9:0x0 r10:0x5 r11:0x246 r12:0xc0000677a8 r13:0x1 r14:0xc000006e00 r15:0x1 rip:0x40332e eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0x119 fs_base:0xc000048898 gs_base:0x0
  { tid:557372, addr:0xc000067774, length:(nil) }
}
{
  real_time:426777.743321 global_time:5079, event:`SYSCALL: clock_gettime' (state:ENTERING_SYSCALL) tid:557372, ticks:41324
rax:0xffffffffffffffda rbx:0xc000048808 rcx:0xffffffffffffffff rdx:0xc000067db8 rsi:0xc000067d80 rdi:0x1 rbp:0xc000067da8 rsp:0xc000067d78 r8:0x0 r9:0x0 r10:0x5 r11:0x246 r12:0xc000067d98 r13:0x1 r14:0xc000006e00 r15:0x1 rip:0x6ffff030 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xe4 fs_base:0xc000048898 gs_base:0x0
}
{
  real_time:426777.743349 global_time:5080, event:`SYSCALL: clock_gettime' (state:EXITING_SYSCALL) tid:557372, ticks:41324
rax:0x0 rbx:0xc000048808 rcx:0xffffffffffffffff rdx:0xc000067db8 rsi:0xc000067d80 rdi:0x1 rbp:0xc000067da8 rsp:0xc000067d78 r8:0x0 r9:0x0 r10:0x5 r11:0x246 r12:0xc000067d98 r13:0x1 r14:0xc000006e00 r15:0x1 rip:0x6ffff030 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xe4 fs_base:0xc000048898 gs_base:0x0
  { tid:557372, addr:0xc000067d80, length:0x10 }
}
{
  real_time:426777.743383 global_time:5081, event:`SYSCALL: clock_gettime' (state:ENTERING_SYSCALL) tid:557372, ticks:41372
rax:0xffffffffffffffda rbx:0xc000048808 rcx:0xffffffffffffffff rdx:0xc000067d70 rsi:0xc000067d40 rdi:0x1 rbp:0xc000067d60 rsp:0xc000067d38 r8:0xffffff01 r9:0xc000033250 r10:0x5 r11:0x246 r12:0xc000067d50 r13:0x1 r14:0xc000006e00 r15:0x1 rip:0x6ffff030 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xe4 fs_base:0xc000048898 gs_base:0x0
}
{
  real_time:426777.743411 global_time:5082, event:`SYSCALL: clock_gettime' (state:EXITING_SYSCALL) tid:557372, ticks:41372
rax:0x0 rbx:0xc000048808 rcx:0xffffffffffffffff rdx:0xc000067d70 rsi:0xc000067d40 rdi:0x1 rbp:0xc000067d60 rsp:0xc000067d38 r8:0xffffff01 r9:0xc000033250 r10:0x5 r11:0x246 r12:0xc000067d50 r13:0x1 r14:0xc000006e00 r15:0x1 rip:0x6ffff030 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xe4 fs_base:0xc000048898 gs_base:0x0
  { tid:557372, addr:0xc000067d40, length:0x10 }
}
{
  real_time:426777.743446 global_time:5083, event:`SYSCALL: epoll_pwait' (state:ENTERING_SYSCALL) tid:557372, ticks:41533
rax:0xffffffffffffffda rbx:0x4 rcx:0xffffffffffffffff rdx:0x80 rsi:0xc000067774 rdi:0x4 rbp:0xc000067718 rsp:0xc0000676d0 r8:0x0 r9:0x0 r10:0x1 r11:0x246 r12:0xc0000677a8 r13:0x1 r14:0xc000006e00 r15:0x1 rip:0x40332e eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0x119 fs_base:0xc000048898 gs_base:0x0
}
{
  real_time:426777.743805 global_time:5084, event:`SYSCALL: futex' (state:EXITING_SYSCALL) tid:557371, ticks:33921
rax:0xffffffffffffff92 rbx:0x0 rcx:0xffffffffffffffff rdx:0x0 rsi:0x80 rdi:0x547960 rbp:0xc00002bec8 rsp:0xc00002be80 r8:0x0 r9:0x0 r10:0xc00002beb8 r11:0x246 r12:0xc00002beb8 r13:0xc000049008 r14:0xc000006540 r15:0x3ffffffffffff rip:0x467aa3 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xca fs_base:0xc000048098 gs_base:0x0
}
{
  real_time:426777.743839 global_time:5085, event:`SYSCALL: clock_gettime' (state:ENTERING_SYSCALL) tid:557371, ticks:33925
rax:0xffffffffffffffda rbx:0xc000048008 rcx:0xffffffffffffffff rdx:0xc00002bed8 rsi:0xc00002bea0 rdi:0x1 rbp:0xc00002bec8 rsp:0xc00002be98 r8:0x0 r9:0x0 r10:0xc00002beb8 r11:0x246 r12:0xc00002beb8 r13:0xc000049008 r14:0xc000006540 r15:0x3ffffffffffff rip:0x6ffff030 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xe4 fs_base:0xc000048098 gs_base:0x0
}
{
  real_time:426777.743866 global_time:5086, event:`SYSCALL: clock_gettime' (state:EXITING_SYSCALL) tid:557371, ticks:33925
rax:0x0 rbx:0xc000048008 rcx:0xffffffffffffffff rdx:0xc00002bed8 rsi:0xc00002bea0 rdi:0x1 rbp:0xc00002bec8 rsp:0xc00002be98 r8:0x0 r9:0x0 r10:0xc00002beb8 r11:0x246 r12:0xc00002beb8 r13:0xc000049008 r14:0xc000006540 r15:0x3ffffffffffff rip:0x6ffff030 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xe4 fs_base:0xc000048098 gs_base:0x0
  { tid:557371, addr:0xc00002bea0, length:0x10 }
}
{
  real_time:426777.743899 global_time:5087, event:`SYSCALL: clock_gettime' (state:ENTERING_SYSCALL) tid:557371, ticks:33945
rax:0xffffffffffffffda rbx:0xc000048008 rcx:0xffffffffffffffff rdx:0xc00002bf38 rsi:0xc00002bf00 rdi:0x1 rbp:0xc00002bf28 rsp:0xc00002bef8 r8:0x0 r9:0x0 r10:0xc00002beb8 r11:0x246 r12:0xc00002bf18 r13:0xc000049008 r14:0xc000006540 r15:0x3ffffffffffff rip:0x6ffff030 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xe4 fs_base:0xc000048098 gs_base:0x0
}
{
  real_time:426777.743926 global_time:5088, event:`SYSCALL: clock_gettime' (state:EXITING_SYSCALL) tid:557371, ticks:33945
rax:0x0 rbx:0xc000048008 rcx:0xffffffffffffffff rdx:0xc00002bf38 rsi:0xc00002bf00 rdi:0x1 rbp:0xc00002bf28 rsp:0xc00002bef8 r8:0x0 r9:0x0 r10:0xc00002beb8 r11:0x246 r12:0xc00002bf18 r13:0xc000049008 r14:0xc000006540 r15:0x3ffffffffffff rip:0x6ffff030 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xe4 fs_base:0xc000048098 gs_base:0x0
  { tid:557371, addr:0xc00002bf00, length:0x10 }
}
{
  real_time:426777.743959 global_time:5089, event:`SYSCALL: nanosleep' (state:ENTERING_SYSCALL) tid:557371, ticks:33989
rax:0xffffffffffffffda rbx:0x14 rcx:0xffffffffffffffff rdx:0x0 rsi:0x0 rdi:0xc00002bf18 rbp:0xc00002bf28 rsp:0xc00002bf18 r8:0x0 r9:0x0 r10:0xc00002beb8 r11:0x246 r12:0xc00002bf18 r13:0xc000049008 r14:0xc000006540 r15:0x3ffffffffffff rip:0x4674d7 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0x23 fs_base:0xc000048098 gs_base:0x0
}
{
  real_time:426777.744025 global_time:5090, event:`SYSCALL: nanosleep' (state:EXITING_SYSCALL) tid:557371, ticks:33989
rax:0x0 rbx:0x14 rcx:0xffffffffffffffff rdx:0x0 rsi:0x0 rdi:0xc00002bf18 rbp:0xc00002bf28 rsp:0xc00002bf18 r8:0x0 r9:0x0 r10:0xc00002beb8 r11:0x246 r12:0xc00002bf18 r13:0xc000049008 r14:0xc000006540 r15:0x3ffffffffffff rip:0x4674d7 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0x23 fs_base:0xc000048098 gs_base:0x0
}
{
  real_time:426777.744057 global_time:5091, event:`SYSCALL: clock_gettime' (state:ENTERING_SYSCALL) tid:557371, ticks:33991
rax:0xffffffffffffffda rbx:0xc000048008 rcx:0xffffffffffffffff rdx:0xc00002bf38 rsi:0xc00002bf00 rdi:0x1 rbp:0xc00002bf28 rsp:0xc00002bef8 r8:0x0 r9:0x0 r10:0xc00002beb8 r11:0x246 r12:0xc00002bf18 r13:0xc000049008 r14:0xc000006540 r15:0x3ffffffffffff rip:0x6ffff030 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xe4 fs_base:0xc000048098 gs_base:0x0
}
{
  real_time:426777.744085 global_time:5092, event:`SYSCALL: clock_gettime' (state:EXITING_SYSCALL) tid:557371, ticks:33991
rax:0x0 rbx:0xc000048008 rcx:0xffffffffffffffff rdx:0xc00002bf38 rsi:0xc00002bf00 rdi:0x1 rbp:0xc00002bf28 rsp:0xc00002bef8 r8:0x0 r9:0x0 r10:0xc00002beb8 r11:0x246 r12:0xc00002bf18 r13:0xc000049008 r14:0xc000006540 r15:0x3ffffffffffff rip:0x6ffff030 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xe4 fs_base:0xc000048098 gs_base:0x0
  { tid:557371, addr:0xc00002bf00, length:0x10 }
}
{
  real_time:426777.744118 global_time:5093, event:`SYSCALL: clock_gettime' (state:ENTERING_SYSCALL) tid:557371, ticks:34035
rax:0xffffffffffffffda rbx:0xc000048008 rcx:0xffffffffffffffff rdx:0xc00002bf38 rsi:0xc00002bf00 rdi:0x1 rbp:0xc00002bf28 rsp:0xc00002bef8 r8:0x0 r9:0x0 r10:0xc00002beb8 r11:0x246 r12:0xc00002bf18 r13:0xc000049008 r14:0xc000006540 r15:0x3ffffffffffff rip:0x6ffff030 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xe4 fs_base:0xc000048098 gs_base:0x0
}
{
  real_time:426777.744146 global_time:5094, event:`SYSCALL: clock_gettime' (state:EXITING_SYSCALL) tid:557371, ticks:34035
rax:0x0 rbx:0xc000048008 rcx:0xffffffffffffffff rdx:0xc00002bf38 rsi:0xc00002bf00 rdi:0x1 rbp:0xc00002bf28 rsp:0xc00002bef8 r8:0x0 r9:0x0 r10:0xc00002beb8 r11:0x246 r12:0xc00002bf18 r13:0xc000049008 r14:0xc000006540 r15:0x3ffffffffffff rip:0x6ffff030 eflags:0x246 cs:0x33 ss:0x2b ds:0x0 es:0x0 fs:0x0 gs:0x0 orig_rax:0xe4 fs_base:0xc000048098 gs_base:0x0
  { tid:557371, addr:0xc00002bf00, length:0x10 }
}
[FATAL src/log.cc:463:emergency_debug()] (session doesn't look interactive, aborting emergency debugging)
=== Start rr backtrace:
rr(_ZN2rr13dump_rr_stackEv+0x5a)[0x60179df817ca]
rr(_ZN2rr15notifying_abortEv+0x14)[0x60179df83564]
rr(+0x2057c4)[0x60179dfa37c4]
rr(+0xcaa6e)[0x60179de68a6e]
rr(+0xcb6ef)[0x60179de696ef]
rr(_ZN2rr13ReplaySession23check_ticks_consistencyEPNS_10ReplayTaskERKNS_5EventE+0x1ed)[0x60179defb27d]
rr(_ZN2rr13ReplaySession11replay_stepERKNS0_15StepConstraintsE+0x9f6)[0x60179df039e6]
rr(_ZN2rr14ReplayTimeline19replay_step_forwardENS_10RunCommandE+0xbb)[0x60179df1f06b]
rr(_ZN2rr9GdbServer14debug_one_stepERNS_10GdbRequestE+0x338)[0x60179de51a28]
rr(_ZN2rr9GdbServer12serve_replayERKNS0_15ConnectionFlagsE+0xaeb)[0x60179de5349b]
rr(+0x15934a)[0x60179def734a]
rr(_ZN2rr13ReplayCommand3runERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE+0x622)[0x60179def8a72]
rr(main+0x1a1)[0x60179ddeb871]
/lib/x86_64-linux-gnu/libc.so.6(+0x29d90)[0x730eacc29d90]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80)[0x730eacc29e40]
rr(_start+0x25)[0x60179ddee355]
=== End rr backtrace
    rr_test.go:48: failed assertion at rr_test.go:145: Continue() - EOF
--- FAIL: TestReverseBreakpointCounts (1.50s)
FAIL
FAIL    github.com/go-delve/delve/pkg/proc/gdbserial    1.511s
FAIL

We should create a separate issue to track this. In the meantime I can restrict my changes to only run when we have a debugserver backend (non-rr). We really need a builder for RR but that is kind of difficult due to limitations around RR in virtualized environments.

@derekparker
Copy link
Member Author

Created #3717 for RR failures not related to this PR.

Copy link
Member

@aarzilli aarzilli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have run the tests with rr and they pass.

pkg/proc/gdbserial/gdbserver.go Outdated Show resolved Hide resolved
if jstopInfo != nil {
_, shouldQueryStopInfo = jstopInfo[th.ID]
}
if shouldQueryStopInfo {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't get this change. If we have a jsonstop record for the thread we do a second query to get a stock packet for the thread? We do this regardless of whether we know if the backend supports the qThreadStopInfo packet?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, as of now I'm only limiting the number of stopInfo packets we send to the threads listed in jstopinfo. That way we don't issue stop info packets for every thread, every time, only the ones we know are in some interesting state.

There is a further optimization which I've noted in the TODO comment where we use only the jstopinfo packet when present and avoid sending any stopInfo packets at all. I've held off on doing that in this PR as the change will be more involved and I didn't want to add too much noise to this patch, so I'm going to send that in as a follow up.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However I did fix the issue with not taking support of qThreadStopInfo into account.

pkg/proc/gdbserial/gdbserver_conn.go Show resolved Hide resolved
This change optimizes the gdbwire backend by reducing the number of
round trips we have to make to debugserver. It does this by using the
jstopinfo packet to only query threads which we know to have a stop
reason, and it also uses the registers returned by the 'T' packet
to avoid issuing a bunch of 'p' packets to get the register values.
@aarzilli aarzilli merged commit 4f28742 into go-delve:master May 15, 2024
2 checks passed
@derekparker derekparker deleted the wip/optimize-gdbwire branch May 15, 2024 16:06
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.

None yet

2 participants