parseHitCondition rebuilt the same regexp from a MustCompile literal on
every call. Move hitConditionRegex to package scope so the pattern is
compiled once at initialization while keeping parseHitCondition behavior
unchanged.
Detecting uint overflow when computing Base+stride*count already sets
v.Unreadable, but execution continued into memory prefetch and element
loading with inconsistent state. Return immediately like other guard
clauses in this function.
SeekToTypeNamed, FindEntryNamed, and NextMemberVariable used for loops
whose condition only tested entry != nil before running the body. When
Next or NextType returned a non-nil error with a nil entry, the loop
exited without inspecting err, returning not-found or nil instead of the
failure. Restructure iteration to always handle errors first.
The token.OR branch required both operands to pass satisf recursively,
matching AND semantics incorrectly. Use logical disjunction so hit-count
fast paths treat disjunctive breakpoint conditions accurately.
AddressToOffset compared virtual addresses with strict inequality against
each executable ELF section load address. PCs landing exactly on Section
.Addr were never matched while still within [Addr, Addr+Size).
Use inclusive lower bounds so the scan matches the usual VMA half-open
interval.
newCompositeMemory ignored errors from MemoryReadWriter.ReadMemory when
building address-based DWARF fragments, so failed reads silently produced
zero-filled data. Return a wrapped error with size and address context,
consistent with RegPiece failures.
ptraceGetGRegs ignored the return value from sys.PtraceGetRegs, so
registers() never reported syscall failures when reading general purpose
registers. Assign the error and normalize syscall.Errno(0) to nil like
other ptrace helpers.
ptraceSetGRegs ignored the return value from sys.PtraceSetRegs, so
setPC and SetReg never reported syscall failures when writing general
purpose registers. Assign the error and normalize errno(0) to nil like
the rest of the ptrace helpers.
* proc: fix SP calculation for sigpanic frames on arm64
Without this fix, stack traces from linux/arm64 core dumps showed SP
values that differed from the runtime's panic output.
Fixes#3591
* Update withCoreFile
The change introduced to fix#4302 happens to conflict with a similar
workaround in debug/macho I forgot exists.
The telemetry report was probably from a binary that legitimately did
not have a debug_line_str section (but referenced it) and we just
misidentified the cause, the fix however is still worth keeping since
there are versions of Go without the workaround that could be affected.
Fixes#4311
TestWaitFor could have the following sequence of events:
1. cmd.Start() is called.
2. The process is started in the kernel.
3. CreateToolhelp32Snapshot (inside waitForSearchProcess) sees
the process and returns from native.WaitFor.
4. The test immediately deferences cmd.Process, but cmd.Process
has not been assigned yet in cmd.Start() -> nil panic.
This patch fixes the issue by introducing a channel that is
written to from testWaitForSetup() _after_ cmd.Start() returns.
Unlike the mutex + boolean, this channel can be waited upon
without spinning, and only then cmd.Process is read inside
the test code.
Mach-O limits the names of sections to the first 16 characters, this
truncates the names of some DWARFv5 sections, meaning we can't find
them by simply calling debug/macho.(*File).Section. Work around this
limitation by looking for a section with the truncated name.
Fixes a panic while parsing DWARFv5 debug_line header on macOS when
DW_FORM_line_strp is used.
Fixes#4302
* First draft implementation to print procedure parameters in trace
* Added code to propagate verbosity flag to terminal side also and
modified tests for expected output
* make output of function return consistent with function call for verbose level=0
* Regenerate Documentation file
* addressed review comments
* Making output at verbosity level 0 consistent with default output and
other comments
* regenerate Documentation file
* Addressed more review comments and refactored code based on recent commit
on pretty print API
* static check build error
* addressed review comment and removed superflous function
* fixed comment, and ran go fmt
* removed incorrect nomenclature from comments
* Add validation tests for traces with verbosity levels
* Correct output format for some types
* Remove TraceVerbosity from breakpoint and keep it in the terminal to
use it only for formatting
* Correct TraceVerbose tests to assert on output incl. formatting just like other trace tests
* remove leftorver t.Logf
* Cleaned up code, renamed trace-verbose to verbose and -V to -v
* proc/internal/ebpf,build: extend eBPF tracing type support and update Docker build
Add support for additional Go types in the eBPF tracing backend:
- Bool: use BoolType with ByteSize 1 instead of IntType with ByteSize 8
- Int/Uint: use actual DWARF size instead of hardcoded ByteSize 8
- Float32/Float64: synthesize FloatType, detect XMM registers as unreadable
- Complex64/Complex128: synthesize ComplexType with XMM detection
- Pointer: capture pointer address and dereference pointed-to value via
bpf_probe_read_user in eBPF C code
- Slice: capture slice header (ptr+len+cap) and dereference element data
- Graceful degradation: map, chan, interface, func, struct, and array
types now produce specific "not yet supported" errors instead of
generic "type not supported by ebpf"
Add Unreadable field to RawUProbeParam so the Go-side parser can
propagate specific error messages through to Variable display.
Update eBPF build infrastructure:
- Replace EOL Ubuntu 21.04 base image with Ubuntu 22.04
- Use clang-12 (required: newer clang generates BPF code that fails
the kernel verifier with "dereference of modified ctx ptr disallowed")
- Update Go from 1.17 to 1.24
- Remove sudo requirement from build-ebpf-builder-img.sh
- Add -u flag to Docker run to avoid root-owned output files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* dwarf/godwarf,proc: fix slice ReflectKind and address PR review feedback
Fix a bug in the DWARF type parser where SliceType.ReflectKind was not
set (stayed 0/reflect.Invalid). When parsing struct types, the code
creates a new StructType, sets ReflectKind on it, then for slices
creates a new SliceType and reassigns the pointer — losing the
ReflectKind. The String case already had an explicit fix for this
(str.ReflectKind = reflect.String), but the Slice case was missing it.
This caused the eBPF tracing backend (which uses dt.Common().ReflectKind
to determine type kind) to see kind=0 for slice parameters, making them
appear as unsupported types. The ptrace backend was unaffected because it
uses Go type assertions (case *godwarf.SliceType) instead of ReflectKind.
Also addresses PR review feedback:
- Add t.Parallel() to TestTraceEBPFTypes subtests
- Use regexp matching for pointer/slice address verification
- Add content verification for slice test output
- Add comment explaining -u flag in build-ebpf-objects.sh
- Add comment explaining amd64-only XMM register threshold
- Handle CreateCompositeMemory errors in target.go
- Remove debug prints from target.go
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: document eBPF type support pipeline and TestTraceEBPFTypes
Add documentation for the eBPF type support pipeline, currently
supported types, the canonical test (TestTraceEBPFTypes) for adding
new type support, and the clang-12 build constraint.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* proc/internal/ebpf: clarify pointer/slice comments per review
Clarify that the eBPF probe does capture dereferenced data, but
loadValue runs Go-side after the probe returns and cannot follow
pointer chains through fake memory addresses. Also remove unicode
arrow from XMM register comment.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* proc/internal/ebpf: clarify pointer/slice deref_val limitations
Explain why we display raw addresses instead of dereferenced values:
element type info isn't propagated through the eBPF pipeline, and
deref_val is limited to 48 bytes which is insufficient for nested
or variable-length types.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* address review feedback
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
TestWaitFor was flaky on Windows. This seems to be linked to
prefix-based matching, where the fixture process spawned by
one test could be waited upon by another test. Adding a
unique no-op argument to different invocations of the
same fixture binary appears to fix the flakiness issue.
* proc: fix stack watch breaklet index for recorded replay
When adding the extra WatchOutOfScope breakpoint at the CALL before the
return PC, the code used len(retbp.Breaklets) to index into retbp2.Breaklets.
If the return address already had other breaklets (e.g. a user breakpoint),
that index could be out of range.
Add TestWatchpointStackRecordedOutOfScopeBreakletIndex (runs with -backend=rr)
to cover this path.
* fix: review
Cover some cases that were not handled by the implementation. Also in
the version of the code in DAP use the proc.Variable directly, avoiding
the roundtrip through a string.
* dwarf/op: fix DW_OP_shr and DW_OP_shra evaluation
DW_OP_shr must perform a logical right shift (zero-fill) and DW_OP_shra an
arithmetic right shift (sign-extend). The two cases were swapped, so
negative values were wrong for location expressions.
Add a regression test that exercises both opcodes with a negative value.
* add,space,trigger ci
* revert
* Update go.mod
* Update go.mod
Provide an online documentation for the configuration file parameters
and the 'config' command.
Until now the configuration parameters were only documented in the
default configuration file and in the source code, neither of which is
very discoverable.
Adds caching to stacktraces so that stacktrace requests are not
quadratic. Also add a Skip parameter to the Stacktrace RPC request so
that clients can only request the frames they need.
Fixes#3809Fixes#989
In some circumstances PrologueEndPC and FirstStmt could return a PC
that is before the start PC that was passed to them.
It is not certain that this is what caused the crash in the issue
because it couldn't be reproduced with a real Go binary, but it looks
like the only possible cause.
Fix#4269
* service/dap,proc: tolerate debuginfod events in tests
When debuginfod is available on the system (e.g. Fedora), asynchronous
"Download debug info" output events can arrive during DAP sessions and
EventBinaryInfoDownload events can appear in the proc event stream.
Tests were not expecting these and would fail.
Fix the DAP test client to skip debuginfod download output events in
ExpectMessage, and fix TestBreakpointMaterializedEvent to search for the
materialized event rather than assuming it is the first event.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* proc: fix test failures with Go 1.27 (gotip)
TestClassicMap: replace panic with t.Skip since the noswissmap
GOEXPERIMENT was removed in Go 1.27.
TestRangeOverFuncNextInlined: extend skip to all Go >= 1.24. The
inlined range-over-func symbol name issue (#3882) still requires a
compiler fix that has not landed in 1.27.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* cmd/dlv: skip TestStaticcheck on development versions of Go
Staticcheck output depends on the Go version used to build it. When
running against a development version (e.g. gotip), the output will
not match the checked-in baseline, causing spurious failures.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
go.mod specifies 1.24, so it's not possible to compile the
tests with Go toolchains <= 1.23 anyway. It doesn't make
sense to skip certain tests for older toolchains, because
attempting to use old toolchains will fail at build time.
* proc: support debugging non-Go binaries that dlopen Go shared libraries
Add support for debugging non-Go stub binaries that dynamically load Go
shared libraries via dlopen or other dynamic linkage modes. When the
initial binary has no Go runtime symbols or DWARF info, Delve now marks
it as non-Go and defers Go-specific initialization. A breakpoint on the
dynamic linker's _dl_debug_state function detects shared library loads,
allowing Delve to pick up Go debug info when a Go .so is loaded at
runtime.
* proc: address PR review feedback for non-Go binary debugging
- Deduplicate auxv parsing by extracting searchAuxv helper
- Rename IsNonGo to IsGo (positive flag is easier to reason about)
- Move Go image detection into loadDebugInfoMaps to avoid reparsing
debug_info; uses DW_AT_language == DW_LANG_Go which is already
checked there for cu.isgo
- Remove hasGoProducer function (no longer needed)
- Remove pkg/proc import from pkg/terminal/command.go; use string
literal for stop reason comparison instead
- Update CLAUDE.md with DWARF parsing and layer boundary guidance
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace SinglelineStringFormatted, SinglelineStringWithShortTypes and
MultilineString with a single configurable StringWithOptions.
The Variable type was starting to have too many formatting helper methods.
Keep SinglelineString since it's used everywhere.
Co-authored-by: Shang Jian Ding <rifflegrass@gmail.com>
* pkg/debugdetect: add package for detecting debugger attachment
Implement new pkg/debugdetect package that detects if a program is
running under a debugger on Linux, macOS, Windows, and FreeBSD.
Platform-specific detection methods:
- Linux: Parse /proc/self/status for TracerPid field
- macOS: Use sysctl with KERN_PROC_PID to check P_TRACED flag
- Windows: Call IsDebuggerPresent() Win32 API
- FreeBSD: Try sysctl first, fall back to /proc/curproc/status
Fixes#4243
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The fix adds validation at every point where pointers are dereferenced
or struct fields are accessed:
- loadTypes: check dirPtr after maybeDereference for both small map
(dirLen <= 0) and large map (dirLen > 0) paths.
- loadCurrentTable: check tab after maybeDereference; check all
toField() returns for the index, groups, groups.data, and
groups.lengthMask fields; extend existing groups nil check to also
check Unreadable.
- loadCurrentGroup: check toField() returns for slots and ctrl fields.
In all cases, the map is marked as Unreadable with a descriptive error
message rather than panicking.
Fixes#4005
Adds a comprehensive parity test ensuring ptrace and eBPF trace backends
produce identical output, preventing formatting divergence as new types
are added.
The test revealed and fixes several eBPF formatting issues:
1. Goroutine format: Now uses "goroutine(N):" to match ptrace
2. Return value format: Now uses ">> goroutine(N): func => (val)"
3. String capture bug: Strings were showing as empty - fixed by adding
StringType to eBPF helpers so string values are properly loaded
Test coverage:
- Fixture tests all currently supported types: int64, uint64, bool,
string
- Runs dlv trace with both backends on same function
- Compares outputs byte-for-byte (filtering process exit messages)
- Updated all existing eBPF test expectations to match new format
All eBPF trace tests now pass with consistent formatting between
backends.
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* goversion: Fix ProducerAfterOrEqual comparison for devel builds
The VersionAfterOrEqual function uses the versionedDevel constant
whereas ProducerAfterOrEqual used 0. This can cause inconsistency
when comparing the "same" version string in different situations.
One of the tests: TestRangeOverFuncNext/TestGotoA1 passes for
gotip due to two wrongs making a right. In particular, the use
of 1.26devel as the version ended up being treated as >= 1.26
because the code was using VersionAfterOrEqual.
However, the logic here was incorrectly using runtime.Version(),
which is logically wrong. It should instead use the Go version
used to compile the binary (the same in CI), and then use
ProducerAfterOrEqual (which would have given a different result).
So we also fix the check in TestGotoA1 to use p.BinInfo().Producer()
and ProducerAfterOrEqual().
* Undo change to use p.BinInfo().Producer()