mirror of
https://github.com/JetSetIlly/Gopher2600.git
synced 2024-05-20 13:48:02 -04:00
fixed callstack/callers output
This commit is contained in:
parent
749940cad9
commit
121d5f9cd6
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue