Skip to content

Support printing function parameters with varying verbosity levels [0 .. 4] with the -trace option#4251

Open
archanaravindar wants to merge 4 commits intogo-delve:masterfrom
archanaravindar:funcp
Open

Support printing function parameters with varying verbosity levels [0 .. 4] with the -trace option#4251
archanaravindar wants to merge 4 commits intogo-delve:masterfrom
archanaravindar:funcp

Conversation

@archanaravindar
Copy link
Contributor

Fixes #3586
The current implementation supports the following verbosity levels
Verbosity Levels:

  • Level 0: No parameter output (just function name)
  • Level 1: Type names only (e.g., <int>, <Person>)
  • Level 2: Inline values, limited depth (default)
  • Level 3: Multi-line, expanded detail
  • Level 4: Full detail with pointer dereferencing

To give an idea of what the output looks like pls refer to the attached .go test file and the related output seen with -trace and -trace-follow options
plainout.txt
testout.txt
traceverbcomplex.zip

stackdepth = 20
}
// Get LoadConfig based on verbosity level
loadCfg := api.GetLoadConfigForVerbosity(traceVerbose)
Copy link
Member

Choose a reason for hiding this comment

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

Why is this a function in a different package?

traceCommand.Flags().String("output", "", "Output path for the binary.")
must(traceCommand.MarkFlagFilename("output"))
traceCommand.Flags().IntVarP(&traceFollowCalls, "follow-calls", "", 0, "Trace all children of the function to the required depth. Trace also supports defer functions and cases where functions are dynamically returned and passed as parameters.")
traceCommand.Flags().IntVarP(&traceVerbose, "trace-verbose", "V", 2, "Parameter verbosity: 0=none, 1=types, 2=inline, 3=expanded, 4=full (default 2)")
Copy link
Member

@aarzilli aarzilli Feb 3, 2026

Choose a reason for hiding this comment

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

I would expect the default to be the same thing we do now, for backwards compatibility. We don't guarantee backwards compatibility for this but I don't see a compelling reason not to do it in this case.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I agree with this.


// Get verbosity level from breakpoint
verbosity := 0
if th.Breakpoint != nil {
Copy link
Member

Choose a reason for hiding this comment

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

We already know th.Breakpoint != nil here.

// TraceFollowCalls indicates the Depth of tracing
TraceFollowCalls int
// Verbosity level to print function parameters as part of the trace [0-4]
TraceVerbosity int
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 think this belongs here. The only piece of code that uses it (as far as I can see), can just check the value of LoadArgs.

fmt.Fprintf(t.stdout, "%s> %s %s%s\n%s\n",
depthPrefix, tracePrefix, bpname, fn.Name(), paramStr)
} else {
// Levels 0-2: Single-line format
Copy link
Member

Choose a reason for hiding this comment

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

These two branches do the same thing.

paramStr := formatTraceParameters(th, verbosity)
if verbosity >= 3 && paramStr != "" {
// Levels 3-4: Multi-line format
fmt.Fprintf(t.stdout, "%s> %s %s%s\n%s\n",
Copy link
Member

Choose a reason for hiding this comment

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

Move the common parts of these Fprintf calls out of the if.

// Print trace only if there was a match on the function while TraceFollowCalls is on or if it's a regular trace
if rootindex != -1 || th.Breakpoint.TraceFollowCalls <= 0 {
fmt.Fprintf(t.stdout, "%s>> %s %s => (%s)\n", depthPrefix, tracePrefix, fn.Name(), strings.Join(retVals, ","))
if verbosity > 0 {
Copy link
Member

Choose a reason for hiding this comment

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

Move the common parts of the fmt.Fprintf calls out of the if.

withTestTerminal("issue573", t, func(term *FakeTerminal) {
term.MustExec("trace foo")
out, _ := term.Exec("continue")
fmt.Printf("output %s\n", out)
Copy link
Member

Choose a reason for hiding this comment

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

t.Logf

}

// FormatWithVerbosity formats a variable according to trace verbosity level
func (v *Variable) FormatWithVerbosity(verbosity int) string {
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 a helper function that is only used by the pkg/terminal package, it belongs there.

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.

Can dlv trace print the value of the arguments passed to a function?

3 participants