(pid uint32, ubuf *UnwindBuf)
| 185 | } |
| 186 | |
| 187 | func (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 | |
| 243 | func (this *MapsHelper) TryManualUpdateMaps(pid uint32, content []byte) error { |
| 244 | maps_lock.Lock() |
no test coverage detected