Skip to main content

Overview

The debug package contains several sub-packages that provide access to program debug information in various binary formats. These packages allow you to read and parse debug data from executables.

Sub-packages

debug/buildinfo

Provides access to information embedded in a Go binary about how it was built.

Types

BuildInfo
type
Type alias for runtime/debug.BuildInfo containing build information.

Functions

ReadFile
func(name string) (*BuildInfo, error)
Returns build information embedded in a Go binary file at the given path.
info, err := buildinfo.ReadFile("/path/to/binary")
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Go version: %s\n", info.GoVersion)
Read
func(r io.ReaderAt) (*BuildInfo, error)
Returns build information embedded in a Go binary file accessed through the given ReaderAt.

debug/dwarf

Provides access to DWARF debugging information loaded from executable files.

Types

Data
type
Represents the DWARF debugging information loaded from an executable file.
type Data struct {
    // contains filtered or unexported fields
}
Entry
type
Represents a single entry in the DWARF debug information.
type Entry struct {
    Offset   Offset
    Tag      Tag
    Children bool
    Field    []Field
}
Tag
type
Identifies the kind of entry.
type Tag uint32
Common tags:
  • TagArrayType
  • TagClassType
  • TagEntryPoint
  • TagEnumerationType
  • TagFormalParameter
  • TagMember
  • TagPointerType
  • TagStructureType
  • TagSubprogram
  • TagTypedef
  • TagVariable
Type
interface
Represents a type in the DWARF type information.
type Type interface {
    Common() *CommonType
    String() string
    Size() int64
}

Methods on Data

Reader
func() *Reader
Returns a new Reader for Data. The reader is positioned at byte offset 0 in the DWARF info section.
Type
func(off Offset) (Type, error)
Returns the Type at the given offset in the DWARF type information.

debug/elf

Implements access to ELF object files.

Types

File
type
Represents an open ELF file.
type File struct {
    FileHeader
    Sections  []*Section
    Progs     []*Prog
    // contains filtered or unexported fields
}
Section
type
Represents a single section in an ELF file.
type Section struct {
    SectionHeader
    // contains filtered or unexported fields
}

Functions

Open
func(name string) (*File, error)
Opens the named file using os.Open and prepares it for use as an ELF binary.
f, err := elf.Open("/bin/ls")
if err != nil {
    log.Fatal(err)
}
defer f.Close()
NewFile
func(r io.ReaderAt) (*File, error)
Creates a new File for accessing an ELF binary in an underlying reader.

Methods on File

Close
func() error
Closes the File.
DWARF
func() (*dwarf.Data, error)
Returns the DWARF debug information for the ELF file.
Section
func(name string) *Section
Returns a section with the given name, or nil if no such section exists.

debug/gosym

Provides access to the Go symbol and line number tables embedded in Go binaries generated by the gc compilers.

Types

Table
type
Represents a Go symbol table.
type Table struct {
    Syms  []Sym
    Funcs []Func
    Files map[string]*Obj
    Objs  []Obj
}
Sym
type
Represents a single symbol table entry.
type Sym struct {
    Value  uint64
    Type   byte
    Name   string
    GoType uint64
    Func   *Func
}

debug/macho

Implements access to Mach-O object files (macOS binaries).

Types

File
type
Represents an open Mach-O file.
type File struct {
    FileHeader
    Loads    []Load
    Sections []*Section
    // contains filtered or unexported fields
}

Functions

Open
func(name string) (*File, error)
Opens the named file using os.Open and prepares it for use as a Mach-O binary.
NewFile
func(r io.ReaderAt) (*File, error)
Creates a new File for accessing a Mach-O binary in an underlying reader.

debug/pe

Implements access to PE (Microsoft Windows Portable Executable) files.

Types

File
type
Represents an open PE file.
type File struct {
    FileHeader
    OptionalHeader any
    Sections       []*Section
    Symbols        []*Symbol
    // contains filtered or unexported fields
}

Functions

Open
func(name string) (*File, error)
Opens the named file using os.Open and prepares it for use as a PE binary.
f, err := pe.Open("C:\\Windows\\notepad.exe")
if err != nil {
    log.Fatal(err)
}
defer f.Close()
NewFile
func(r io.ReaderAt) (*File, error)
Creates a new File for accessing a PE binary in an underlying reader.

debug/plan9obj

Implements access to Plan 9 a.out object files.

Types

File
type
Represents an open Plan 9 a.out file.
type File struct {
    FileHeader
    Sections []*Section
    // contains filtered or unexported fields
}

Functions

Open
func(name string) (*File, error)
Opens the named file using os.Open and prepares it for use as a Plan 9 a.out binary.

Examples

Reading Build Info

package main

import (
    "debug/buildinfo"
    "fmt"
    "log"
)

func main() {
    info, err := buildinfo.ReadFile("/path/to/binary")
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("Go Version: %s\n", info.GoVersion)
    fmt.Printf("Path: %s\n", info.Path)
    
    for _, dep := range info.Deps {
        fmt.Printf("Dependency: %s %s\n", dep.Path, dep.Version)
    }
}

Reading ELF File

package main

import (
    "debug/elf"
    "fmt"
    "log"
)

func main() {
    f, err := elf.Open("/bin/ls")
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()
    
    fmt.Printf("Type: %s\n", f.Type)
    fmt.Printf("Machine: %s\n", f.Machine)
    
    for _, section := range f.Sections {
        fmt.Printf("Section: %s (size: %d)\n", section.Name, section.Size)
    }
}

Reading DWARF Information

package main

import (
    "debug/elf"
    "fmt"
    "log"
)

func main() {
    f, err := elf.Open("./myprogram")
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()
    
    dwarf, err := f.DWARF()
    if err != nil {
        log.Fatal(err)
    }
    
    reader := dwarf.Reader()
    for {
        entry, err := reader.Next()
        if err != nil {
            log.Fatal(err)
        }
        if entry == nil {
            break
        }
        
        if entry.Tag == dwarf.TagSubprogram {
            name, ok := entry.Val(dwarf.AttrName).(string)
            if ok {
                fmt.Printf("Function: %s\n", name)
            }
        }
    }
}

Reading PE File (Windows)

package main

import (
    "debug/pe"
    "fmt"
    "log"
)

func main() {
    f, err := pe.Open("C:\\Windows\\notepad.exe")
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()
    
    fmt.Printf("Machine: %v\n", f.Machine)
    fmt.Printf("Sections: %d\n", len(f.Sections))
    
    for _, section := range f.Sections {
        fmt.Printf("  %s: size=%d\n", section.Name, section.Size)
    }
}

Use Cases

  • Binary Analysis: Inspect compiled binaries to understand their structure
  • Debugging Tools: Build custom debugging and profiling tools
  • Build Information: Extract version and dependency information from binaries
  • Symbol Resolution: Map addresses to function names and source locations
  • Cross-platform Analysis: Analyze binaries from different platforms

Build docs developers (and LLMs) love