mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 02:36:18 +08:00 
			
		
		
		
	proc: bugfix: Truncate stacktrace when FDE of a frame can not be found
Instead of returning an error when FDE of a frame can not be found, just truncate the stack trace. Fixes #462
This commit is contained in:
		| @ -65,6 +65,14 @@ func NewFrameIndex() FrameDescriptionEntries { | ||||
| 	return make(FrameDescriptionEntries, 0, 1000) | ||||
| } | ||||
|  | ||||
| type NoFDEForPCError struct { | ||||
| 	PC uint64 | ||||
| } | ||||
|  | ||||
| func (err *NoFDEForPCError) Error() string { | ||||
| 	return fmt.Sprintf("could not find FDE for PC %#v", err.PC) | ||||
| } | ||||
|  | ||||
| // Returns the Frame Description Entry for the given PC. | ||||
| func (fdes FrameDescriptionEntries) FDEForPC(pc uint64) (*FrameDescriptionEntry, error) { | ||||
| 	idx := sort.Search(len(fdes), func(i int) bool { | ||||
| @ -77,7 +85,7 @@ func (fdes FrameDescriptionEntries) FDEForPC(pc uint64) (*FrameDescriptionEntry, | ||||
| 		return true | ||||
| 	}) | ||||
| 	if idx == len(fdes) { | ||||
| 		return nil, fmt.Errorf("could not find FDE for PC %#v", pc) | ||||
| 		return nil, &NoFDEForPCError{pc} | ||||
| 	} | ||||
| 	return fdes[idx], nil | ||||
| } | ||||
|  | ||||
| @ -1655,3 +1655,33 @@ func TestPanicBreakpoint(t *testing.T) { | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func TestIssue462(t *testing.T) { | ||||
| 	// Stacktrace of Goroutine 0 fails with an error | ||||
| 	if runtime.GOOS == "windows" { | ||||
| 		return | ||||
| 	} | ||||
| 	withTestProcess("testnextnethttp", t, func(p *Process, fixture protest.Fixture) { | ||||
| 		go func() { | ||||
| 			for !p.Running() { | ||||
| 				time.Sleep(50 * time.Millisecond) | ||||
| 			} | ||||
|  | ||||
| 			// Wait for program to start listening. | ||||
| 			for { | ||||
| 				conn, err := net.Dial("tcp", "localhost:9191") | ||||
| 				if err == nil { | ||||
| 					conn.Close() | ||||
| 					break | ||||
| 				} | ||||
| 				time.Sleep(50 * time.Millisecond) | ||||
| 			} | ||||
|  | ||||
| 			p.RequestManualStop() | ||||
| 		}() | ||||
|  | ||||
| 		assertNoError(p.Continue(), t, "Continue()") | ||||
| 		_, err := p.CurrentThread.Stacktrace(40) | ||||
| 		assertNoError(err, t, "Stacktrace()") | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @ -4,6 +4,7 @@ import ( | ||||
| 	"encoding/binary" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"github.com/derekparker/delve/dwarf/frame" | ||||
| ) | ||||
|  | ||||
| // NoReturnAddr is returned when return address | ||||
| @ -101,6 +102,12 @@ func (it *StackIterator) Next() bool { | ||||
| 	} | ||||
| 	it.frame, it.err = it.dbp.frameInfo(it.pc, it.sp, it.top) | ||||
| 	if it.err != nil { | ||||
| 		if _, nofde := it.err.(*frame.NoFDEForPCError); nofde && !it.top { | ||||
| 			it.frame = Stackframe{ Current: Location{ PC: it.pc, File: "?", Line: -1  }, Call: Location{ PC: it.pc, File: "?", Line: -1 }, CFA: 0, Ret: 0 } | ||||
| 			it.atend = true | ||||
| 			it.err = nil | ||||
| 			return true | ||||
| 		} | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
|  | ||||
| @ -3,6 +3,7 @@ package proc | ||||
| import ( | ||||
| 	"debug/gosym" | ||||
| 	"encoding/binary" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"path/filepath" | ||||
| 	"reflect" | ||||
| @ -353,6 +354,9 @@ func (thread *Thread) Scope() (*EvalScope, error) { | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if len(locations) < 1 { | ||||
| 		return nil, errors.New("could not decode first frame") | ||||
| 	} | ||||
| 	return locations[0].Scope(thread), nil | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -422,11 +422,13 @@ func (g *G) UserCurrent() Location { | ||||
| 	it := newStackIterator(g.dbp, pc, sp) | ||||
| 	for it.Next() { | ||||
| 		frame := it.Frame() | ||||
| 		if frame.Call.Fn != nil { | ||||
| 			name := frame.Call.Fn.Name | ||||
| 			if (strings.Index(name, ".") >= 0) && (!strings.HasPrefix(name, "runtime.") || isExportedRuntime(name)) { | ||||
| 				return frame.Call | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return g.CurrentLoc | ||||
| } | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 aarzilli
					aarzilli