mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 10:47:27 +08:00 
			
		
		
		
	Ensure breakpoint is set only once
This commit is contained in:
		| @ -20,6 +20,13 @@ type DebuggedProcess struct { | |||||||
| 	Executable   *elf.File | 	Executable   *elf.File | ||||||
| 	Symbols      []elf.Symbol | 	Symbols      []elf.Symbol | ||||||
| 	GoSymTable   *gosym.Table | 	GoSymTable   *gosym.Table | ||||||
|  | 	BreakPoints  map[string]*BreakPoint | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type BreakPoint struct { | ||||||
|  | 	FunctionName string | ||||||
|  | 	Line         int | ||||||
|  | 	Addr         uint64 | ||||||
| } | } | ||||||
|  |  | ||||||
| // Returns a new DebuggedProcess struct with sensible defaults. | // Returns a new DebuggedProcess struct with sensible defaults. | ||||||
| @ -44,6 +51,7 @@ func NewDebugProcess(pid int) (*DebuggedProcess, error) { | |||||||
| 		Regs:         &syscall.PtraceRegs{}, | 		Regs:         &syscall.PtraceRegs{}, | ||||||
| 		Process:      proc, | 		Process:      proc, | ||||||
| 		ProcessState: ps, | 		ProcessState: ps, | ||||||
|  | 		BreakPoints:  make(map[string]*BreakPoint), | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err = debuggedProc.LoadInformation() | 	err = debuggedProc.LoadInformation() | ||||||
| @ -79,19 +87,32 @@ func (dbp *DebuggedProcess) Registers() (*syscall.PtraceRegs, error) { | |||||||
| } | } | ||||||
|  |  | ||||||
| // Sets a breakpoint in the running process. | // Sets a breakpoint in the running process. | ||||||
| func (dbp *DebuggedProcess) Break(fname string) error { | func (dbp *DebuggedProcess) Break(fname string) (*BreakPoint, error) { | ||||||
| 	var ( | 	var ( | ||||||
| 		breakpoint = []byte{'0', 'x', 'C', 'C'} | 		int3 = []byte{'0', 'x', 'C', 'C'} | ||||||
| 		fn   = dbp.GoSymTable.LookupFunc(fname) | 		fn   = dbp.GoSymTable.LookupFunc(fname) | ||||||
| 		addr = uintptr(fn.LineTable.PC) | 		addr = uintptr(fn.LineTable.PC) | ||||||
| 	) | 	) | ||||||
|  |  | ||||||
| 	_, err := syscall.PtracePokeData(dbp.Pid, addr, breakpoint) | 	_, ok := dbp.BreakPoints[fname] | ||||||
| 	if err != nil { | 	if ok { | ||||||
| 		return err | 		return nil, fmt.Errorf("Breakpoint already set") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return nil | 	_, err := syscall.PtracePokeData(dbp.Pid, addr, int3) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	breakpoint := &BreakPoint{ | ||||||
|  | 		FunctionName: fn.Name, | ||||||
|  | 		Line:         fn.LineTable.Line, | ||||||
|  | 		Addr:         fn.LineTable.PC, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	dbp.BreakPoints[fname] = breakpoint | ||||||
|  |  | ||||||
|  | 	return breakpoint, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // Steps through process. | // Steps through process. | ||||||
|  | |||||||
| @ -110,7 +110,7 @@ func TestBreakPoint(t *testing.T) { | |||||||
| 		t.Fatal("NewDebugProcess():", err) | 		t.Fatal("NewDebugProcess():", err) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	err = p.Break("main.sleepytime") | 	_, err = p.Break("main.sleepytime") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal("Break():", err) | 		t.Fatal("Break():", err) | ||||||
| 	} | 	} | ||||||
| @ -135,3 +135,26 @@ func TestBreakPoint(t *testing.T) { | |||||||
|  |  | ||||||
| 	cmd.Process.Kill() | 	cmd.Process.Kill() | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func TestBreakPointIsSetOnlyOnce(t *testing.T) { | ||||||
|  | 	cmd, err := StartTestProcess("testprog") | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatal("Starting test process:", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	pid := cmd.Process.Pid | ||||||
|  | 	p, err := NewDebugProcess(pid) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatal("NewDebugProcess():", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	_, err = p.Break("main.sleepytime") | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatal("Break():", err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	_, err = p.Break("main.sleepytime") | ||||||
|  | 	if err == nil { | ||||||
|  | 		t.Fatal("Should not be able to add breakpoint twice") | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Derek Parker
					Derek Parker