Skip to content

Commit c835f8b

Browse files
committed
初步支持offset计算
1 parent 3e37acd commit c835f8b

4 files changed

Lines changed: 73 additions & 16 deletions

File tree

user/event/event_raw_syscalls.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,16 @@ func (this *SyscallEvent) String() string {
111111
case EventTypeSysEnter:
112112
// --getlr 和 --getpc 建议只使用其中一个
113113
if conf.GetLR {
114-
info, err := this.ParseLR()
114+
// info, err := this.ParseLR()
115+
info, err := this.ParseLRV1()
115116
if err != nil {
116117
return fmt.Sprintf("ParseLR err:%v\n", err)
117118
}
118119
return fmt.Sprintf("%s LR:0x%x Info:\n%s\n", base_str, this.lr, info)
119120
}
120121
if conf.GetPC {
121-
info, err := this.ParsePC()
122+
// info, err := this.ParsePC()
123+
info, err := this.ParsePCV1()
122124
if err != nil {
123125
return fmt.Sprintf("ParsePC err:%v\n", err)
124126
}
@@ -151,6 +153,10 @@ func (this *SyscallEvent) String() string {
151153
return base_str
152154
}
153155

156+
func (this *SyscallEvent) ParseLRV1() (string, error) {
157+
return maps_helper.GetOffset(this.Pid, this.lr), nil
158+
}
159+
154160
func (this *SyscallEvent) ParseLR() (string, error) {
155161
info := "UNKNOWN"
156162
// 直接读取maps信息 计算lr在什么地方 定位syscall调用也就一目了然了
@@ -182,6 +188,12 @@ func (this *SyscallEvent) ParseLR() (string, error) {
182188
return info, err
183189
}
184190

191+
func (this *SyscallEvent) ParsePCV1() (string, error) {
192+
// 通过在启动阶段收集到的库基址信息来计算偏移
193+
// 由于每个进程的加载情况不一样 这里要传递 pid
194+
return maps_helper.GetOffset(this.Pid, this.pc), nil
195+
}
196+
185197
func (this *SyscallEvent) ParsePC() (string, error) {
186198
info := "UNKNOWN"
187199
// 直接读取maps信息 计算pc在什么地方 定位syscall调用也就一目了然了

user/event/event_soinfo.go

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,43 @@ import (
99
"fmt"
1010
"stackplz/pkg/util"
1111
"stackplz/user/config"
12+
"strings"
13+
"sync"
1214
)
1315

1416
type LibInfo struct {
15-
Pid uint32
1617
BaseAddr uint64
1718
LibSize uint64
19+
EndAddr uint64
1820
LibPath string
1921
}
2022

2123
type MapsHelper map[uint32]PidMaps
2224
type PidMaps map[string][]LibInfo
2325

24-
func NewMapsHelper() *MapsHelper {
25-
helper := &MapsHelper{}
26+
func NewMapsHelper() MapsHelper {
27+
helper := make(MapsHelper)
2628
return helper
2729
}
2830

2931
func (this *MapsHelper) UpdateMaps(soinfo *SoInfoEvent) {
32+
// 拙劣的函数
33+
maps_lock.Lock()
34+
defer maps_lock.Unlock()
3035
pid_maps, ok := (*this)[soinfo.Pid]
3136
if !ok {
32-
(*this)[soinfo.Pid] = PidMaps{}
37+
pid_maps = make(PidMaps)
38+
(*this)[soinfo.Pid] = pid_maps
39+
}
40+
pid_maps = (*this)[soinfo.Pid]
41+
if soinfo.LibPath == "" {
42+
soinfo.LibPath = fmt.Sprintf("UNNAMED_0x%x", soinfo.BaseAddr)
3343
}
3444
info := LibInfo{
3545
LibSize: soinfo.LibSize,
3646
BaseAddr: soinfo.BaseAddr,
3747
LibPath: soinfo.LibPath,
48+
EndAddr: soinfo.BaseAddr + soinfo.LibSize,
3849
}
3950
base_list, ok := pid_maps[soinfo.LibPath]
4051
if ok {
@@ -48,24 +59,59 @@ func (this *MapsHelper) UpdateMaps(soinfo *SoInfoEvent) {
4859
}
4960
if !has_find {
5061
base_list = append(base_list, info)
62+
pid_maps[soinfo.LibPath] = base_list
5163
}
5264
} else {
5365
pid_maps[soinfo.LibPath] = []LibInfo{info}
5466
}
67+
(*this)[soinfo.Pid] = pid_maps
5568
}
5669

57-
func (this *MapsHelper) GetOffset(addr uint64) (info string) {
58-
return ""
70+
func (this *MapsHelper) GetOffset(pid uint32, addr uint64) (info string) {
71+
maps_lock.Lock()
72+
defer maps_lock.Unlock()
73+
pid_maps, ok := (*this)[pid]
74+
if !ok {
75+
// 暂时没有这个 pid 对应的 maps 信息
76+
return fmt.Sprintf("UNNKOWN + 0x%x", addr)
77+
}
78+
// 这里的计算是以库的每个段都是前后连续为前提的,暂时就这样
79+
// 但是实际上确实存在一些奇怪的操作
80+
// 1. 不连续的段
81+
// 2. 两个或者多个同名/同路径的库存在于maps中
82+
// 3. 其他...
83+
// 全部遍历是一种低效的写法,但是暂时没有更好的想法,就这样
84+
// 一定要优化那么应该在每次 pid_maps 变更的时候就进行排序 并按照基址大小插入
85+
var off_list []string = []string{}
86+
for lib_path, lib_infos := range pid_maps {
87+
for _, lib_info := range lib_infos {
88+
if addr >= lib_info.BaseAddr && addr < lib_info.EndAddr {
89+
offset := fmt.Sprintf("%s + 0x%x", lib_path, addr-lib_info.BaseAddr)
90+
off_list = append(off_list, offset)
91+
}
92+
}
93+
}
94+
if len(off_list) == 0 {
95+
return fmt.Sprintf("NOTFOUND + 0x%x", addr)
96+
}
97+
return strings.Join(off_list[:], ",")
5998
}
6099

100+
// func (this *MapsHelper) toString() (s string) {
101+
// s = ""
102+
// s += fmt.Sprintln(*this)
103+
// return s
104+
// }
105+
61106
var maps_helper = NewMapsHelper()
107+
var maps_lock sync.Mutex
62108

63109
type SoInfoEvent struct {
64110
event_type EventType
65111
KEvent
66-
mconf *config.ModuleConfig
67-
Pid uint32
68-
Tid uint32
112+
mconf *config.ModuleConfig
113+
// Pid uint32
114+
// Tid uint32
69115
Comm [16]byte
70116
BaseAddr uint64
71117
LibSize uint64
@@ -96,7 +142,7 @@ func (this *SoInfoEvent) Decode() (err error) {
96142
return
97143
}
98144
this.LibPath = util.B2STrim(this.RealPath[:])
99-
145+
maps_helper.UpdateMaps(this)
100146
return nil
101147
}
102148

user/event/event_stack.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ import (
1818
type UprobeStackEvent struct {
1919
event_type EventType
2020
KEvent
21-
mconf *config.ModuleConfig
22-
Pid uint32
23-
Tid uint32
21+
mconf *config.ModuleConfig
22+
// Pid uint32
23+
// Tid uint32
2424
Timestamp uint64
2525
Comm [16]byte
2626
// Buffer [256]byte

user/module/imodule.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,6 @@ func (this *Module) ringbufEventReader(errChan chan error, em *ebpf.Map) {
297297
this.logger.Printf("%s\tthis.child.decode error:%v", this.child.Name(), err)
298298
continue
299299
}
300-
301300
// 直接将解析数据交给 processor 做
302301
// 从而加快读取环形缓冲区的数据 减缓数据丢失的概率
303302
this.processor.Write(e)

0 commit comments

Comments
 (0)