为了账号安全,请及时绑定邮箱和手机立即绑定

golang 从编译文件中获取所有文件路径

golang 从编译文件中获取所有文件路径

Go
米琪卡哇伊 2022-01-10 16:40:09
我正在尝试获取在编译期间使用的所有源文件。函数 runtime.Caller() 和带有堆栈跟踪的恐慌显示此信息。我需要这样的东西func fetchUsedFiles() []string {    ....}func main() {    log.Println("Used Files",fetchUsedFiles())}UPS:我需要的只是以某种方式读取“runtime.firstmoduledata”变量内容。但它不是导出变量。
查看完整描述

1 回答

?
凤凰求蛊

TA贡献1825条经验 获得超4个赞

实际上,我已经结合了 VonC 答案和我的运行时方法。


所有需要的数据都存储在runtime.firstmoduledata- struct 但它们不会被导出。要从那里读取数据,我再次读取我的可执行文件(仅针对 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

}


查看完整回答
反对 回复 2022-01-10
  • 1 回答
  • 0 关注
  • 195 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信