fixed callstack/callers output

This commit is contained in:
JetSetIlly 2023-09-21 06:27:14 +01:00
parent 749940cad9
commit 121d5f9cd6
4 changed files with 25 additions and 33 deletions

View file

@ -32,9 +32,6 @@ type CallStack struct {
// list of callers for all executed functions
Callers map[string]([]*dwarf.SourceLine)
// prevLine is helpful when creating the Callers list
PrevLine *dwarf.SourceLine
}
// NewCallStack is the preferred method of initialisation for the CallStack type
@ -60,24 +57,19 @@ func (cs CallStack) WriteCallers(function string, w io.Writer) error {
const maxDepth = 15
var f func(callLines []*dwarf.SourceLine, depth int) error
f = func(callLines []*dwarf.SourceLine, depth int) error {
var f func(lines []*dwarf.SourceLine, depth int) error
f = func(lines []*dwarf.SourceLine, depth int) error {
indent := strings.Builder{}
for i := 0; i < depth; i++ {
indent.WriteString(" ")
indent.WriteString(" ")
}
if depth > maxDepth {
return errors.New(fmt.Sprintf("%stoo deep", indent.String()))
}
for _, ln := range callLines {
if ln.IsStub() {
return nil
}
s := fmt.Sprintf("%s (%s:%d)", ln.Function.Name, ln.File.ShortFilename, ln.LineNumber)
w.Write([]byte(fmt.Sprintf("%s%s", indent.String(), s)))
for _, ln := range lines {
w.Write([]byte(fmt.Sprintf("%s%s", indent.String(), ln.Function.Name)))
if l, ok := cs.Callers[ln.Function.Name]; ok {
err := f(l, depth+1)
if err != nil {

View file

@ -86,6 +86,9 @@ type Developer struct {
// keeps track of the previous breakpoint check. see checkBreakPointByAddr()
prevBreakpointCheck *dwarf.SourceLine
// keeps track of the previous line in profiling scan. see processProfiling()
prevProfileLine *dwarf.SourceLine
}
// NewDeveloper is the preferred method of initialisation for the Developer type.

View file

@ -159,7 +159,7 @@ type SourceLine struct {
func (ln *SourceLine) String() string {
if ln.IsStub() {
return ln.PlainContent
return ""
}
s := strings.Builder{}
s.WriteString(fmt.Sprintf("%s:%d", ln.File.ShortFilename, ln.LineNumber))

View file

@ -70,29 +70,29 @@ func (dev *Developer) ProcessProfiling() {
defer dev.callstackLock.Unlock()
for _, p := range dev.profiler.Entries {
l := len(dev.callstack.Stack)
lastLn := dev.callstack.Stack[l-1]
// line of executed instruction. every instruction should have an
// associated line/function. if it does not then we assume it is in
// the entry function
// the driver function
ln, ok := dev.source.LinesByAddress[uint64(p.Addr)]
if !ok {
ln = dev.source.DriverSourceLine
dev.source.LinesByAddress[uint64(p.Addr)] = ln
}
// if function has changed
if ln != lastLn {
popped := false
// callstack
l := len(dev.callstack.Stack)
prevCallStack := dev.callstack.Stack[l-1]
// try to pop
// change callstack if function has changed
if ln.Function != prevCallStack.Function {
var popped bool
// try to pop entry from callstack
var i int
for i = 1; i <= l; i++ {
for i = 1; i <= l && !popped; i++ {
if ln.Function == dev.callstack.Stack[l-i].Function {
chop := dev.callstack.Stack[l-i+1:]
dev.callstack.Stack = dev.callstack.Stack[:l-i+1]
popped = true
// flag functions which look like they are part of an
// optimised call stack
@ -102,7 +102,8 @@ func (dev *Developer) ProcessProfiling() {
}
}
break // for loop
// setting popped will cause the loop to end early
popped = true
}
}
@ -110,10 +111,6 @@ func (dev *Developer) ProcessProfiling() {
if !popped {
dev.callstack.Stack = append(dev.callstack.Stack, ln)
// there is always at least one entry in the functions callstack so we can
// confidently subtract two from the length after the append above
// prev := dev.callstack.functions[len(dev.callstack.functions)-2]
// create/update callers list for function
var n int
l, ok := dev.callstack.Callers[ln.Function.Name]
@ -122,15 +119,15 @@ func (dev *Developer) ProcessProfiling() {
return ln == l[i]
})
}
if !ok || (n > len(l) && l[n] != dev.callstack.PrevLine) {
l = append(l, dev.callstack.PrevLine)
if !ok || (n > len(l) && l[n] != dev.prevProfileLine) {
l = append(l, dev.prevProfileLine)
sort.Slice(l, func(i, j int) bool {
return l[i].Function.Name < l[j].Function.Name
})
dev.callstack.Callers[ln.Function.Name] = l
}
}
}
// accumulate counts for line (and the line's function)
@ -142,7 +139,7 @@ func (dev *Developer) ProcessProfiling() {
}
// record line for future comparison
dev.callstack.PrevLine = ln
dev.prevProfileLine = ln
}
// empty slice