我正在查看类型为debug/gosym
的软件包gosym.Table
,据称它是Go可执行文件的符号表。不幸的是,我没有看到任何从正在运行的程序中提取sysmbol表的方法(缺少Go反射,并且我需要的信息比它所提供的更多,尤其是导出符号的名称)。
如果通常不可能,但是可以在Linux上/对于ELF二进制文件,也可以选择。
要获取go(Linux)中当前正在运行的进程的符号表:
var symTable *gosym.Table
var symTableLoadFailed bool
func loadSymbolTableLinux() {
if symTable != nil || symTableLoadFailed {
return
}
// Try to load from memory first
const elfStartAddress = uintptr(0x400000)
const maxSize = 0x10000000
processMemory := (*[maxSize]byte)(unsafe.Pointer(elfStartAddress))[:maxSize:maxSize]
exe, err := elf.NewFile(bytes.NewReader(processMemory))
if err != nil {
// Failing that, load a copy from disk
exePath, err := os.Executable()
if err != nil {
symTableLoadFailed = true
log.Printf("subvert: Error finding executable: %v", err)
return
}
exe, err = elf.Open(exePath)
if err != nil {
symTableLoadFailed = true
log.Printf("subvert: Error opening %v: %v", exePath, err)
return
}
}
defer exe.Close()
lineTableData, err := exe.Section(".gopclntab").Data()
if err != nil {
symTableLoadFailed = true
log.Printf("subvert: Error reading .gopclntab data: %v", err)
return
}
addr := exe.Section(".text").Addr
lineTable := gosym.NewLineTable(lineTableData, addr)
symTable, err = gosym.NewTable([]byte{}, lineTable)
if err != nil {
symTableLoadFailed = true
log.Printf("subvert: Error creating symbol table: %v", err)
symTable = nil
}
}
也在此处实现:https://github.com/kstenerud/go-subvert/blob/master/subvert.go#L165