Skip to content

Commit

Permalink
test debug/gosym
Browse files Browse the repository at this point in the history
  • Loading branch information
wlingze committed Apr 3, 2024
1 parent 0f69ac9 commit f28fec1
Showing 1 changed file with 109 additions and 0 deletions.
109 changes: 109 additions & 0 deletions tests/gosym_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package main

import (
"bytes"
"debug/buildinfo"
"debug/elf"
"debug/gosym"
"encoding/binary"
"strings"
"testing"
)

func getPclntab(file *elf.File) *elf.Section {

sectionLabel := ".gopclntab"
section := file.Section(sectionLabel)
if section != nil {
return section
}
// binary may be built with -pie
sectionLabel = ".data.rel.ro.gopclntab"
section = file.Section(sectionLabel)
if section != nil {
return section
}
sectionLabel = ".data.rel.ro"
section = file.Section(sectionLabel)
if section != nil {
return section
}
return nil
}

// From go/src/debug/gosym/pclntab.go
const (
go12magic = 0xfffffffb
go116magic = 0xfffffffa
go118magic = 0xfffffff0
go120magic = 0xfffffff1
)

// Select the magic number based on the Go version
func magicNumber(goVersion string) []byte {
bs := make([]byte, 4)
var magic uint32
if strings.Compare(goVersion, "go1.20") >= 0 {
magic = go120magic
} else if strings.Compare(goVersion, "go1.18") >= 0 {
magic = go118magic
} else if strings.Compare(goVersion, "go1.16") >= 0 {
magic = go116magic
} else {
magic = go12magic
}
binary.LittleEndian.PutUint32(bs, magic)
return bs
}

const FuncitonName = "crypto/tls.(*Conn).Read"

func TestDockerSymbolFromPclntab(t *testing.T) {
path := "./docker_binary/arm64"

// Read the build information of the Go application
buildInfo, err := buildinfo.ReadFile(path)
if err != nil {
t.Fatal("get biuldinfo error:", err)
}

file, err := elf.Open(path)
if err != nil {
t.Fatal("elf open error:", err)
}

section := getPclntab(file)
if section == nil {
t.Fatalf("con't get pclntab")
}

tableData, err := section.Data()
if err != nil {
t.Fatalf("found section but could not read pclntab from %s ", path)
}
// Find .gopclntab by magic number even if there is no section label
magic := magicNumber(buildInfo.GoVersion)
pclntabIndex := bytes.Index(tableData, magic)
if pclntabIndex < 0 {
t.Fatalf("could not find magic number in %s ", path)
}
tableData = tableData[pclntabIndex:]

addr := file.Section(".text").Addr
lineTable := gosym.NewLineTable(tableData, addr)
symTable, err := gosym.NewTable([]byte{}, lineTable)
if err != nil {
t.Fatalf("gosym.NewTable error: ", err)
}
// when this symTab builded, this function address is error,
// this functino index = 6626,
// you can set condition breakpoint in `/usr/lib/go/src/debug/gosym/pclntab.go:308` with `i==6626`, this code build this functino.
f := symTable.LookupFunc(FuncitonName)
if f == nil {
t.Fatalf("con't looup symbol %s", FuncitonName)
}
if f.Value != readFuncAddress {
t.Fatalf("error symbol address: got[0x%08x] vs want[0x%08x]", f.Value, readFuncAddress)
}

}

0 comments on commit f28fec1

Please sign in to comment.