MCPcopy Create free account
hub / github.com/SeeFlowerX/stackplz / GetStack

Method GetStack

user/event/event_mmap2.go:187–241  ·  view source on GitHub ↗
(pid uint32, ubuf *UnwindBuf)

Source from the content-addressed store, hash-verified

185}
186
187func (this *MapsHelper) GetStack(pid uint32, ubuf *UnwindBuf) (info string, err error) {
188 // 当直接读取 maps 文件失败的时候 就采用这个方案获取堆栈
189 maps_lock.Lock()
190 defer maps_lock.Unlock()
191 // 首先尝试获取 pid 对应的 maps 信息
192 pid_maps, ok := this.pid_maps[pid]
193 if !ok {
194 return "", errors.New(fmt.Sprintf("[GetStack] get pid_maps failed by pid:%d", pid))
195 }
196
197 // perf_output_sample_ustack dump获取到的栈空间数据 起始地址就是 sp
198 stack_buf := bytes.NewReader(ubuf.Data[:])
199 fp := ubuf.Regs[common.REG_ARM64_X29]
200 // lr := ubuf.Regs[common.REG_ARM64_LR]
201 sp := ubuf.Regs[common.REG_ARM64_SP]
202 pc := ubuf.Regs[common.REG_ARM64_PC]
203 // 栈解析结果
204 // var stack_arr []uint64
205 var stack_infos []string
206 // stack_arr = append(stack_arr, pc)
207 stack_infos = append(stack_infos, this.GetRegionInfo(pid_maps, pc))
208 // 奇怪 这里竟然没有 sp 所在的map信息
209 // sp_region := this.GetRegion(pid_maps, sp)
210 // this.logger.Printf("start:0x%x end:0x%x name:%s\n", sp_region.BaseAddr, sp_region.EndAddr, sp_region.LibName)
211 // this.logger.Printf("pc:0x%x fp:0x%x sp:0x%x\n", pc, fp, sp)
212 for i := 0; i < 20; i++ {
213 // if fp < sp || fp < sp_region.BaseAddr || fp > sp_region.EndAddr {
214 // break
215 // }
216 if fp < sp {
217 break
218 }
219 fp_offset := fp - sp
220 stack_buf.Seek(int64(fp_offset), io.SeekStart)
221 var next_fp uint64
222 err = binary.Read(stack_buf, binary.LittleEndian, &next_fp)
223 if err != nil {
224 this.logger.Printf("read next_fp at offset:0x%x failed\n", fp_offset)
225 break
226 }
227 var next_lr uint64
228 err = binary.Read(stack_buf, binary.LittleEndian, &next_lr)
229 if err != nil {
230 this.logger.Printf("read next_lr at offset:0x%x failed\n", fp_offset+uint64(binary.Size(next_fp)))
231 break
232 }
233 fp = next_fp
234 if next_lr != 0 {
235 stack_infos = append(stack_infos, this.GetRegionInfo(pid_maps, next_lr))
236 }
237 }
238 backtrace := fmt.Sprintf("\t%s", strings.Join(stack_infos, "\n\t"))
239 return backtrace, nil
240 // return this.GetOffset(pid, addr), nil
241}
242
243func (this *MapsHelper) TryManualUpdateMaps(pid uint32, content []byte) error {
244 maps_lock.Lock()

Callers 2

ParseContextStackMethod · 0.80
ParseContextStackMethod · 0.80

Calls 1

GetRegionInfoMethod · 0.95

Tested by

no test coverage detected