golang 从编译文件中获取所有文件路径
golang fetch all all filepathes from compiled file
我正在尝试获取编译期间使用的所有源文件。
函数 runtime.Caller() 和 panic 及其堆栈跟踪显示此信息。
我需要这样的东西
func fetchUsedFiles() []string {
....
}
func main() {
log.Println("Used Files",fetchUsedFiles())
}
更新:
我所需要的只是以某种方式读取 "runtime.firstmoduledata" 变量内容。但它不是导出变量。
实际上我结合了 VonC 答案和我的运行时方法。
所有需要的数据都存储在 runtime.firstmoduledata
- 结构中,但不会导出。为了从那里读取数据,我再次读取我的可执行文件(仅针对 ELF 实现),找到这个符号并执行其他部分,如 runtime.Caller() 函数。此方法不可移植,可能会因运行时库的更改而中断,但它有效。
selfReflect
函数使用运行时库中私有类型的副本
https://github.com/martende/restartable/blob/master/restartable.go#L208
func selfReflect(filename string) ([]string,error) {
f,err := elf.Open(filename)
if err != nil {
return nil,err
}
defer f.Close()
syms,err := f.Symbols()
if err != nil {
return nil,err
}
var modSym elf.Symbol
var modSymFound = false
for _,v := range syms {
if v.Name == "runtime.firstmoduledata" {
modSym = v
modSymFound = true
break
}
}
if ! modSymFound {
return nil,errors.New("elfparse:nosym")
}
var datap = (*moduledata)(unsafe.Pointer(uintptr(modSym.Value)))
files := make([]string,0)
for i := range datap.filetab {
bp := &datap.pclntable[datap.filetab[i]]
file := C.GoString( (*C.char) (unsafe.Pointer(bp)) )
if file != "<autogenerated>" && file != "@" {
if _, err := os.Stat(file); err == nil {
files = append(files ,file)
}
}
}
return files,nil
}
我正在尝试获取编译期间使用的所有源文件。 函数 runtime.Caller() 和 panic 及其堆栈跟踪显示此信息。
我需要这样的东西
func fetchUsedFiles() []string {
....
}
func main() {
log.Println("Used Files",fetchUsedFiles())
}
更新:
我所需要的只是以某种方式读取 "runtime.firstmoduledata" 变量内容。但它不是导出变量。
实际上我结合了 VonC 答案和我的运行时方法。
所有需要的数据都存储在 runtime.firstmoduledata
- 结构中,但不会导出。为了从那里读取数据,我再次读取我的可执行文件(仅针对 ELF 实现),找到这个符号并执行其他部分,如 runtime.Caller() 函数。此方法不可移植,可能会因运行时库的更改而中断,但它有效。
selfReflect
函数使用运行时库中私有类型的副本
https://github.com/martende/restartable/blob/master/restartable.go#L208
func selfReflect(filename string) ([]string,error) {
f,err := elf.Open(filename)
if err != nil {
return nil,err
}
defer f.Close()
syms,err := f.Symbols()
if err != nil {
return nil,err
}
var modSym elf.Symbol
var modSymFound = false
for _,v := range syms {
if v.Name == "runtime.firstmoduledata" {
modSym = v
modSymFound = true
break
}
}
if ! modSymFound {
return nil,errors.New("elfparse:nosym")
}
var datap = (*moduledata)(unsafe.Pointer(uintptr(modSym.Value)))
files := make([]string,0)
for i := range datap.filetab {
bp := &datap.pclntable[datap.filetab[i]]
file := C.GoString( (*C.char) (unsafe.Pointer(bp)) )
if file != "<autogenerated>" && file != "@" {
if _, err := os.Stat(file); err == nil {
files = append(files ,file)
}
}
}
return files,nil
}