-
Notifications
You must be signed in to change notification settings - Fork 0
/
stack_table.go
90 lines (72 loc) · 1.84 KB
/
stack_table.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package wbpf
import (
"unsafe"
"github.com/cilium/ebpf"
)
const MAX_STACK_DEPTH = 127
type StackTraceT struct {
InsPtr [MAX_STACK_DEPTH]uint64
}
type StackTable struct{ *Table }
func NewStackTable(tbl *Table) (*StackTable, error) {
if tbl == nil {
return nil, ErrTableIsNil
}
if tbl.TableType() != ebpf.StackTrace {
return nil, ErrIncorrectTableType
}
return &StackTable{tbl}, nil
}
func (t *StackTable) GetStackAddr(stackid int64, clear bool) []uint64 {
if stackid < 0 {
return nil
}
id := uint32(stackid)
var b []byte
if b, _ = t.LookupBytes(id); len(b) == 0 {
log.Tracef("Failed to lookup key 0x%08x", stackid)
return nil
}
stack := (*StackTraceT)(unsafe.Pointer(&b[0]))
var addrs []uint64
for i := 0; i < MAX_STACK_DEPTH && stack.InsPtr[i] != 0; i++ {
addrs = append(addrs, stack.InsPtr[i])
}
if clear {
if err := t.Delete(id); err != nil {
log.WithError(err).Tracef("Failed to delete key 0x%08x", stackid)
return nil
}
}
return addrs
}
func (t *StackTable) ClearStackId(stackid int64) {
if stackid < 0 {
return
}
if err := t.Delete(uint32(stackid)); err != nil {
log.WithError(err).Tracef("Failed to delete key 0x%08x", stackid)
}
}
func (t *StackTable) GetAddrSymbol(pid int, addr uint64, opts ResolveSymbolOptions) string {
if pid < 0 {
return t.mod.ResolveKernelSymbol(addr, opts)
}
return t.mod.ResolveSymbol(pid, addr, opts)
}
func (st *StackTraceT) ToBytes() []byte {
if st == nil {
return nil
}
// Get the size of the struct
size := unsafe.Sizeof(StackTraceT{})
// Create a byte slice with the same size as the struct
b := make([]byte, size)
// Create an unsafe pointer to the struct
ptr := unsafe.Pointer(st)
// Use a loop to copy the bytes from the struct to the byte slice
for i := 0; i < int(size); i++ {
b[i] = *(*byte)(unsafe.Pointer(uintptr(ptr) + uintptr(i)))
}
return b
}