| // Copyright 2017 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package core | |
| import ( | |
| "testing" | |
| ) | |
| // loadTest loads a simple core file which resulted from running the | |
| // following program on linux/amd64 with go 1.9.0 (the earliest supported runtime): | |
| // package main | |
| // func main() { | |
| // _ = *(*int)(nil) | |
| // } | |
| func loadExample(t *testing.T) *Process { | |
| p, err := Core("testdata/core", "testdata") | |
| if err != nil { | |
| t.Fatalf("can't load test core file: %s", err) | |
| } | |
| return p | |
| } | |
| // TestMappings makes sure we can find and load some data. | |
| func TestMappings(t *testing.T) { | |
| p := loadExample(t) | |
| s, err := p.Symbols() | |
| if err != nil { | |
| t.Errorf("can't read symbols: %s\n", err) | |
| } | |
| a := s["main.main"] | |
| m := p.findMapping(a) | |
| if m == nil { | |
| t.Errorf("text mapping missing") | |
| } | |
| if m.Perm() != Read|Exec { | |
| t.Errorf("bad code section permissions") | |
| } | |
| if opcode := p.ReadUint8(a); opcode != 0x31 { | |
| // 0x31 = xorl instruction. | |
| // There's no particular reason why this instruction | |
| // is first. This just tests that reading code works | |
| // for our specific test binary. | |
| t.Errorf("opcode=0x%x, want 0x31", opcode) | |
| } | |
| a = s["runtime.class_to_size"] | |
| m = p.findMapping(a) | |
| if m == nil { | |
| t.Errorf("data mapping missing") | |
| } | |
| if m.Perm() != Read|Write { | |
| t.Errorf("bad data section permissions") | |
| } | |
| if size := p.ReadUint16(a.Add(2)); size != 8 { | |
| t.Errorf("class_to_size[1]=%d, want 8", size) | |
| } | |
| } | |
| // TestConfig checks the configuration accessors. | |
| func TestConfig(t *testing.T) { | |
| p := loadExample(t) | |
| if arch := p.Arch(); arch != "amd64" { | |
| t.Errorf("arch=%s, want amd64", arch) | |
| } | |
| if size := p.PtrSize(); size != 8 { | |
| t.Errorf("ptrSize=%d, want 8", size) | |
| } | |
| if log := p.LogPtrSize(); log != 3 { | |
| t.Errorf("logPtrSize=%d, want 3", log) | |
| } | |
| if bo := p.ByteOrder(); bo.String() != "LittleEndian" { | |
| t.Errorf("got %s, want LittleEndian", bo) | |
| } | |
| } | |
| // TestThread makes sure we get information about running threads. | |
| func TestThread(t *testing.T) { | |
| p := loadExample(t) | |
| syms, err := p.Symbols() | |
| if err != nil { | |
| t.Errorf("can't read symbols: %s\n", err) | |
| } | |
| raise := syms["runtime.raise"] | |
| var size int64 = 1 << 30 | |
| for _, a := range syms { | |
| if a > raise && a.Sub(raise) < size { | |
| size = a.Sub(raise) | |
| } | |
| } | |
| found := false | |
| for _, thr := range p.Threads() { | |
| if thr.PC() >= raise && thr.PC() < raise.Add(size) { | |
| found = true | |
| } | |
| } | |
| if !found { | |
| t.Errorf("can't find thread that did runtime.raise") | |
| } | |
| } |