mirror of
				https://github.com/go-delve/delve.git
				synced 2025-11-01 03:42:59 +08:00 
			
		
		
		
	Further isolate Linux specific code
This commit is contained in:
		| @ -4,25 +4,13 @@ import ( | ||||
| 	"debug/gosym" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"sync" | ||||
| 	"syscall" | ||||
|  | ||||
| 	"github.com/derekparker/delve/dwarf/frame" | ||||
| 	"github.com/derekparker/delve/vendor/elf" | ||||
| ) | ||||
|  | ||||
| // Struct representing a debugged process. Holds onto pid, register values, | ||||
| // process struct and process state. | ||||
| type DebuggedProcess struct { | ||||
| 	Pid           int | ||||
| 	Process       *os.Process | ||||
| 	Executable    *elf.File | ||||
| 	GoSymTable    *gosym.Table | ||||
| 	FrameEntries  *frame.FrameDescriptionEntries | ||||
| 	BreakPoints   map[uint64]*BreakPoint | ||||
| 	Threads       map[int]*ThreadContext | ||||
| 	CurrentThread *ThreadContext | ||||
| } | ||||
|  | ||||
| func (dbp *DebuggedProcess) addThread(tid int) (*ThreadContext, error) { | ||||
| 	err := syscall.PtraceSetOptions(tid, syscall.PTRACE_O_TRACECLONE) | ||||
| 	if err == syscall.ESRCH { | ||||
| @ -60,20 +48,97 @@ func parseProcessStatus(pid int) (*ProcessStatus, error) { | ||||
| 	return &ps, nil | ||||
| } | ||||
|  | ||||
| func (dbp *DebuggedProcess) findExecutable() error { | ||||
| // Finds the executable from /proc/<pid>/exe and then | ||||
| // uses that to parse the following information: | ||||
| // * Dwarf .debug_frame section | ||||
| // * Dwarf .debug_line section | ||||
| // * Go symbol table. | ||||
| func (dbp *DebuggedProcess) LoadInformation() error { | ||||
| 	var ( | ||||
| 		wg  sync.WaitGroup | ||||
| 		exe *elf.File | ||||
| 		err error | ||||
| 	) | ||||
|  | ||||
| 	exe, err = dbp.findExecutable() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	wg.Add(2) | ||||
| 	go dbp.parseDebugFrame(exe, &wg) | ||||
| 	go dbp.obtainGoSymbols(exe, &wg) | ||||
|  | ||||
| 	wg.Wait() | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (dbp *DebuggedProcess) findExecutable() (*elf.File, error) { | ||||
| 	procpath := fmt.Sprintf("/proc/%d/exe", dbp.Pid) | ||||
|  | ||||
| 	f, err := os.OpenFile(procpath, 0, os.ModePerm) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	elffile, err := elf.NewFile(f) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	dbp.Executable = elffile | ||||
| 	data, err := elffile.DWARF() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	dbp.Dwarf = data | ||||
|  | ||||
| 	return nil | ||||
| 	return elffile, nil | ||||
| } | ||||
|  | ||||
| func (dbp *DebuggedProcess) parseDebugFrame(exe *elf.File, wg *sync.WaitGroup) { | ||||
| 	defer wg.Done() | ||||
|  | ||||
| 	debugFrame, err := exe.Section(".debug_frame").Data() | ||||
| 	if err != nil { | ||||
| 		fmt.Println("could not get .debug_frame section", err) | ||||
| 		os.Exit(1) | ||||
| 	} | ||||
|  | ||||
| 	dbp.FrameEntries = frame.Parse(debugFrame) | ||||
| } | ||||
|  | ||||
| func (dbp *DebuggedProcess) obtainGoSymbols(exe *elf.File, wg *sync.WaitGroup) { | ||||
| 	defer wg.Done() | ||||
|  | ||||
| 	var ( | ||||
| 		symdat  []byte | ||||
| 		pclndat []byte | ||||
| 		err     error | ||||
| 	) | ||||
|  | ||||
| 	if sec := exe.Section(".gosymtab"); sec != nil { | ||||
| 		symdat, err = sec.Data() | ||||
| 		if err != nil { | ||||
| 			fmt.Println("could not get .gosymtab section", err) | ||||
| 			os.Exit(1) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if sec := exe.Section(".gopclntab"); sec != nil { | ||||
| 		pclndat, err = sec.Data() | ||||
| 		if err != nil { | ||||
| 			fmt.Println("could not get .gopclntab section", err) | ||||
| 			os.Exit(1) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	pcln := gosym.NewLineTable(pclndat, exe.Section(".text").Addr) | ||||
| 	tab, err := gosym.NewTable(symdat, pcln) | ||||
| 	if err != nil { | ||||
| 		fmt.Println("could not get initialize line table", err) | ||||
| 		os.Exit(1) | ||||
| 	} | ||||
|  | ||||
| 	dbp.GoSymTable = tab | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Derek Parker
					Derek Parker