Skip to content

Conversation

@archanaravindar
Copy link
Contributor

Is an extension of the basic support added to mention depth upto which functions and their descendants need to be traced #3594
The same option can now trace defer functions and their descendants

Fixes #3743

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 don't really get what this PR is trying to achieve. Right now the trace with depth thing is determining statically from the call graph which functions to trace. This PR seems to change that so that deferred functions are added, at runtime, to the traced functions. Why are we doing this and why only deferred functions and not any other kind of dynamic dispatch?

@archanaravindar
Copy link
Contributor Author

Hi @aarzilli Thank you for reviewing the patch in detail and also suggesting improvements to optimize the code
This patch adds support for functions called from within defer {..} that cant be determined statically unlike other functions so that their execution can be traced more accurately. Defers are handled in this patch specifically because they are an explicit feature of Go and one of the most common dynamic dispatch types used within a Go program

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.

All new code should be gofmt'd.

@aarzilli
Copy link
Member

Defers are handled in this patch specifically because they are an explicit feature of Go and one of the most common dynamic dispatch types used within a Go program

Defers are an explicit feature of Go just like function variables and interfaces, I'm not even sure that they really are the most common type of dynamic dispatch compared to the others (or by how much if they are), but even if they were I'm not sure it's enough to single them out. Or even how you would explain that to users, i.e. this changes the behavior of follow-calls without updating its documentation, but how would you update it "defer calls are followed regardless of what they call but other other types of dynamic calls aren't"?

@archanaravindar
Copy link
Contributor Author

Defers are handled in this patch specifically because they are an explicit feature of Go and one of the most common dynamic dispatch types used within a Go program

Defers are an explicit feature of Go just like function variables and interfaces, I'm not even sure that they really are the most common type of dynamic dispatch compared to the others (or by how much if they are), but even if they were I'm not sure it's enough to single them out. Or even how you would explain that to users, i.e. this changes the behavior of follow-calls without updating its documentation, but how would you update it "defer calls are followed regardless of what they call but other other types of dynamic calls aren't"?

Thank you for the detailed comment @aarzilli, it appears that with minimal modifications the code can trace functions that are dynamically passed as procedure parameters or returned from functions. Made changes to documentation and added couple of test cases for the same, kindly let us know your thoughts on this, Thanks again for your time on this!

@aarzilli
Copy link
Member

Sorry to not have reviewed this yet, but I have been busy this past month and I will continue to be busy for a while still.

@archanaravindar archanaravindar force-pushed the tracedefer branch 2 times, most recently from 61e5bdf to 0ddb9bc Compare August 1, 2025 05:43
@archanaravindar archanaravindar force-pushed the tracedefer branch 2 times, most recently from 59936a7 to 57207b5 Compare September 22, 2025 10:42
// createBreakpointForTracepoints creates a logical breakpoint specifically for tracepoints.
// It handles the BreakpointExistsError by silently ignoring it, as duplicate tracepoints
// are expected during dynamic function discovery.
func (d *Debugger) createBreakpointForTracepoints(lbp *proc.LogicalBreakpoint) error {
Copy link
Member

Choose a reason for hiding this comment

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

This is only ever called by the function below, so maybe we should just create a function variable in the below function like:

tryEnableBreakpoint := func(lbp *proc.LogicalBreakpoint) error { ... }

// createFnTracepoint is a way to create a trace point late in the cycle but just in time that it can be
// included in the trace output as in the case of dynamic functions, we get to know the functions that are
// being called from deferreturn quite late in execution
func createFnTracepoint(d *Debugger, fname string, rootstr string, followCalls int) (*api.Breakpoint, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Sorry to be pedantic, but technically this creates multiple breakpoints (entry, exit), so maybe we rename this to createFunctionTracepoints (note plural).

Copy link
Member

Choose a reason for hiding this comment

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

Also, it doesn't look like any of the callers of this function use the returned *api.Breakpoint so let's just return an error from this function. If callers did need the created breakpoint, it would be better to return all the breakpoints we created, I think (including return tracepoints).

Copy link
Member

@derekparker derekparker left a comment

Choose a reason for hiding this comment

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

LGTM

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.

LGTM

@aarzilli aarzilli merged commit 35ccc94 into go-delve:master Oct 28, 2025
9 of 11 checks passed
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.

Add defer functions to follow-calls tracing option

3 participants