reformat code

This commit is contained in:
zy
2023-12-12 11:55:44 +08:00
parent 636b2df0dd
commit 462bdebad6
10 changed files with 539 additions and 541 deletions

View File

@@ -1,9 +1,9 @@
#include <elf.h>
#include <fcntl.h>
#include <gelf.h> // for GElf_Ehdr | Elf
#include <gelf.h> // for GElf_Ehdr | Elf
#include <libelf.h>
#include <string.h>
#include <unistd.h>
#include <elf.h>
#include <libelf.h>
#include "unwind.h"
@@ -43,7 +43,8 @@ static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, GElf_Shdr *shp,
gelf_getshdr(sec, shp);
str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
if (!strcmp(name, str)) break;
if (!strcmp(name, str))
break;
}
return sec;
@@ -56,12 +57,15 @@ static u64 elf_section_offset(int fd, const char *name) {
u64 offset = 0;
elf = elf_begin(fd, ELF_C_READ_MMAP, NULL);
if (elf == NULL) return 0;
if (elf == NULL)
return 0;
do {
if (gelf_getehdr(elf, &ehdr) == NULL) break;
if (gelf_getehdr(elf, &ehdr) == NULL)
break;
if (!elf_section_by_name(elf, &ehdr, &shdr, name)) break;
if (!elf_section_by_name(elf, &ehdr, &shdr, name))
break;
offset = shdr.sh_offset;
} while (0);
@@ -103,13 +107,16 @@ ssize_t dso_read(vma *dso, u64 offset, u8 *data, ssize_t size) {
int fd;
fd = dso_data_fd(dso);
if (fd < 0) return -1;
if (fd < 0)
return -1;
do {
if (-1 == lseek(fd, offset, SEEK_SET)) break;
if (-1 == lseek(fd, offset, SEEK_SET))
break;
ret = read(fd, data, size);
if (ret <= 0) break;
if (ret <= 0)
break;
} while (0);
close(fd);
@@ -137,14 +144,15 @@ ssize_t dso__data_read_offset(vma *dso, u64 offset, u8 *data, ssize_t size) {
return r;
}
#define dw_read(ptr, type, end) \
({ \
type *__p = (type *)ptr; \
type __v; \
if ((__p + 1) > (type *)end) return -EINVAL; \
__v = *__p++; \
ptr = (typeof(ptr))__p; \
__v; \
#define dw_read(ptr, type, end) \
({ \
type *__p = (type *)ptr; \
type __v; \
if ((__p + 1) > (type *)end) \
return -EINVAL; \
__v = *__p++; \
ptr = (typeof(ptr))__p; \
__v; \
})
static int __dw_read_encoded_value(u8 **p, u8 *end, u64 *val, u8 encoding) {
@@ -152,43 +160,44 @@ static int __dw_read_encoded_value(u8 **p, u8 *end, u64 *val, u8 encoding) {
*val = 0;
switch (encoding) {
case DW_EH_PE_omit:
*val = 0;
goto out;
case DW_EH_PE_ptr:
*val = dw_read(cur, unsigned long, end);
goto out;
default:
break;
case DW_EH_PE_omit:
*val = 0;
goto out;
case DW_EH_PE_ptr:
*val = dw_read(cur, unsigned long, end);
goto out;
default:
break;
}
switch (encoding & DW_EH_PE_APPL_MASK) {
case DW_EH_PE_absptr:
break;
case DW_EH_PE_pcrel:
*val = (unsigned long)cur;
break;
default:
return -EINVAL;
case DW_EH_PE_absptr:
break;
case DW_EH_PE_pcrel:
*val = (unsigned long)cur;
break;
default:
return -EINVAL;
}
if ((encoding & 0x07) == 0x00) encoding |= DW_EH_PE_udata4;
if ((encoding & 0x07) == 0x00)
encoding |= DW_EH_PE_udata4;
switch (encoding & DW_EH_PE_FORMAT_MASK) {
case DW_EH_PE_sdata4:
*val += dw_read(cur, s32, end);
break;
case DW_EH_PE_udata4:
*val += dw_read(cur, u32, end);
break;
case DW_EH_PE_sdata8:
*val += dw_read(cur, s64, end);
break;
case DW_EH_PE_udata8:
*val += dw_read(cur, u64, end);
break;
default:
return -EINVAL;
case DW_EH_PE_sdata4:
*val += dw_read(cur, s32, end);
break;
case DW_EH_PE_udata4:
*val += dw_read(cur, u32, end);
break;
case DW_EH_PE_sdata8:
*val += dw_read(cur, s64, end);
break;
case DW_EH_PE_udata8:
*val += dw_read(cur, u64, end);
break;
default:
return -EINVAL;
}
out:
@@ -196,13 +205,13 @@ out:
return 0;
}
#define dw_read_encoded_value(ptr, end, enc) \
({ \
u64 __v; \
if (__dw_read_encoded_value(&ptr, end, &__v, enc)) { \
return -EINVAL; \
} \
__v; \
#define dw_read_encoded_value(ptr, end, enc) \
({ \
u64 __v; \
if (__dw_read_encoded_value(&ptr, end, &__v, enc)) { \
return -EINVAL; \
} \
__v; \
})
static int unwind_spec_ehframe(vma *dso, u64 offset, u64 *table_data,
@@ -233,7 +242,8 @@ static int read_unwind_spec(vma *dso, u64 *table_data, u64 *segbase,
if (dso->eh_frame_hdr_offset == 0 && dso->elf_read_error == 0) {
fd = dso_data_fd(dso);
if (fd < 0) return -EINVAL;
if (fd < 0)
return -EINVAL;
dso->eh_frame_hdr_offset = elf_section_offset(fd, ".eh_frame_hdr");
close(fd);
@@ -300,7 +310,8 @@ static int get_dyn_info_list_addr(unw_addr_space_t as, unw_word_t *dil_addr,
ssize_t dso__data_read_addr(vma *map, u64 addr, u8 *data, ssize_t size) {
u64 offset;
if (map->name.size() > 0 && map->name[0] != '/') return 0;
if (map->name.size() > 0 && map->name[0] != '/')
return 0;
offset = addr - map->start + map->offset;
return dso__data_read_offset(map, offset, data, size);
@@ -336,7 +347,8 @@ static int access_dso_mem(struct unwind_info *ui, unw_word_t addr,
*/
static int reg_value(unw_word_t *valp, struct regs_dump *regs, int id) {
/* we only support 3 registers. RIP, RSP and RBP */
if (id < 0 || id > 2) return -EINVAL;
if (id < 0 || id > 2)
return -EINVAL;
*valp = regs->regs[id];
return 0;
@@ -411,17 +423,17 @@ int unwind__arch_reg_id(int regnum) {
int id;
switch (regnum) {
case UNW_X86_64_RBP:
id = PERF_REG_BP;
break;
case UNW_X86_64_RSP:
id = PERF_REG_SP;
break;
case UNW_X86_64_RIP:
id = PERF_REG_IP;
break;
default:
return -EINVAL;
case UNW_X86_64_RBP:
id = PERF_REG_BP;
break;
case UNW_X86_64_RSP:
id = PERF_REG_SP;
break;
case UNW_X86_64_RIP:
id = PERF_REG_IP;
break;
default:
return -EINVAL;
}
return id;

View File

@@ -1,8 +1,8 @@
#include "elf.h"
#include <elf.h>
#include <fcntl.h> // for open
#include <gelf.h> // for GElf_Ehdr
#include <fcntl.h> // for open
#include <gelf.h> // for GElf_Ehdr
#include <libelf.h>
#include <string.h>
#include <sys/utsname.h>
@@ -88,7 +88,8 @@ static int get_symbols_in_section(sym_section_ctx *sym, Elf *elf, Elf_Scn *sec,
return -1;
}
sym->sym_count = shdr->sh_size / shdr->sh_entsize; // 获取section中的symbol数量
sym->sym_count =
shdr->sh_size / shdr->sh_entsize; // 获取section中的symbol数量
sym->is_plt = 0;
sym->is_reloc = is_reloc; // 是否是可重定位文件
@@ -120,7 +121,8 @@ static int get_plt_symbols_in_section(sym_section_ctx *sym, Elf *elf,
sym->is_plt = 1;
sym->plt_entsize = plt->plt.hdr->sh_type;
sym->plt_offset = plt->plt.hdr->sh_offset;
sym->sym_count = plt->plt_rel.hdr->sh_size / plt->plt_rel.hdr->sh_entsize; // 获取section中的symbol数量
sym->sym_count = plt->plt_rel.hdr->sh_size /
plt->plt_rel.hdr->sh_entsize; // 获取section中的symbol数量
sym->plt_rel_type = plt->plt_rel.hdr->sh_type;
return 0;
@@ -163,7 +165,8 @@ static void __get_symbol_without_plt(std::set<symbol> &ss, sym_section_ctx *tab,
s.end = s.start + sym.st_size;
s.ip = s.start;
s.name = sym_name;
// printf("name: %s, start: 0x%lx, end: 0x%lx\n", s.name.c_str(), s.start, s.end);
// printf("name: %s, start: 0x%lx, end: 0x%lx\n", s.name.c_str(), s.start,
// s.end);
ss.insert(s);
}
}
@@ -220,7 +223,8 @@ static void __get_plt_symbol(std::set<symbol> &ss, symbol_sections_ctx *si,
s.end = s.start + si->dynsymtab.plt_entsize;
s.ip = s.start;
s.name = sym_name;
// printf("plt name: %s, start: 0x%lx, end: 0x%lx\n", s.name.c_str(), s.start, s.end);
// printf("plt name: %s, start: 0x%lx, end: 0x%lx\n", s.name.c_str(),
// s.start, s.end);
ss.insert(s);
}
}
@@ -235,7 +239,8 @@ static void get_all_symbols(std::set<symbol> &ss, symbol_sections_ctx *si,
// Dwarf_Off die_offset = 0, next_offset;
// size_t header_size;
// printf("1\n");
// while (dwarf_nextcu(dw, die_offset, &next_offset, &header_size, NULL, NULL, NULL) == 0) {
// while (dwarf_nextcu(dw, die_offset, &next_offset, &header_size, NULL, NULL,
// NULL) == 0) {
// printf("2\n");
// Dwarf_Die cudie;
// printf("3\n");
@@ -280,11 +285,11 @@ static void get_all_symbols(std::set<symbol> &ss, symbol_sections_ctx *si,
// }
// }
bool is_stripped(const char* path) {
bool is_stripped(const char *path) {
char command[256];
// snprintf(command, sizeof(command), "file %s", path);
FILE* fp = popen(command, "r");
FILE *fp = popen(command, "r");
if (fp == NULL) {
// handle error
return false;
@@ -298,92 +303,87 @@ bool is_stripped(const char* path) {
}
#define MAX_LINE_LENGTH 1024
void get_symbol_from_elf_gdb(std::set<symbol> &ss, const char *path, size_t file_base_addr = 0)
{
FILE *fp;
char cmd[MAX_LINE_LENGTH];
char line[MAX_LINE_LENGTH];
// 构建 GDB 命令
snprintf(cmd, sizeof(cmd), "gdb -batch -ex \"file %s\" -ex \"info functions\"", path);
void get_symbol_from_elf_gdb(std::set<symbol> &ss, const char *path,
size_t file_base_addr = 0) {
FILE *fp;
char cmd[MAX_LINE_LENGTH];
char line[MAX_LINE_LENGTH];
// 构建 GDB 命令
snprintf(cmd, sizeof(cmd),
"gdb -batch -ex \"file %s\" -ex \"info functions\"", path);
// 执行 GDB 命令并获取输出
fp = popen(cmd, "r");
if (fp == NULL)
{
perror("popen");
return;
// 执行 GDB 命令并获取输出
fp = popen(cmd, "r");
if (fp == NULL) {
perror("popen");
return;
}
bool non_debugging_symbols = false;
std::map<unsigned long long, std::string> symbol_map;
// 读取并解析 GDB 的输出
while (fgets(line, sizeof(line), fp) != NULL) {
unsigned long long address;
char name[MAX_LINE_LENGTH];
// printf("line: %s", line);
if (!non_debugging_symbols) {
if (strstr(line, "Non-debugging symbols:") != NULL) {
non_debugging_symbols = true;
}
continue;
}
bool non_debugging_symbols = false;
std::map<unsigned long long, std::string> symbol_map;
// 读取并解析 GDB 的输出
while (fgets(line, sizeof(line), fp) != NULL)
{
unsigned long long address;
char name[MAX_LINE_LENGTH];
// printf("line: %s", line);
if (!non_debugging_symbols)
{
if (strstr(line, "Non-debugging symbols:") != NULL)
{
non_debugging_symbols = true;
}
continue;
}
char *token = strtok(line, " ");
if (token != NULL)
{
sscanf(token, "%llx", &address);
token = strtok(NULL, "\n");
if (token != NULL)
{
strcpy(name, token);
}
// if name == ":", 跳过
if (name[0] == ':')
{
continue;
}
symbol_map[address] = std::string(name);
}
// 解析函数名和地址
// if (sscanf(line, "%llx %s", &address, name) == 2)
// {
// // if name == ":", 跳过
// if (name[0] == ':')
// {
// continue;
// }
// // printf("Name %s, Address %llx\n", name, address);
// // name -> std::string
// symbol_map[address] = std::string(name);
// }
char *token = strtok(line, " ");
if (token != NULL) {
sscanf(token, "%llx", &address);
token = strtok(NULL, "\n");
if (token != NULL) {
strcpy(name, token);
}
// if name == ":", 跳过
if (name[0] == ':') {
continue;
}
symbol_map[address] = std::string(name);
}
// 解析函数名和地址
// if (sscanf(line, "%llx %s", &address, name) == 2)
// {
// // if name == ":", 跳过
// if (name[0] == ':')
// {
// continue;
// }
// // printf("Name %s, Address %llx\n", name, address);
// // name -> std::string
// symbol_map[address] = std::string(name);
// }
}
symbol s;
symbol s;
// 插入范围到新的map
auto it = symbol_map.begin();
auto next_it = it;
++next_it;
// 插入范围到新的map
auto it = symbol_map.begin();
auto next_it = it;
++next_it;
for (; next_it != symbol_map.end(); ++it, ++next_it)
{
s.start = it->first - file_base_addr;
s.end = next_it->first - file_base_addr;
s.ip = s.start;
s.name = it->second;
// printf("gdb name: %s, start: 0x%lx, end: 0x%lx\n", s.name.c_str(), s.start, s.end);
ss.insert(s);
}
// 关闭 GDB 进程
pclose(fp);
//
for (; next_it != symbol_map.end(); ++it, ++next_it) {
s.start = it->first - file_base_addr;
s.end = next_it->first - file_base_addr;
s.ip = s.start;
s.name = it->second;
// printf("gdb name: %s, start: 0x%lx, end: 0x%lx\n", s.name.c_str(),
// s.start, s.end);
ss.insert(s);
}
// 关闭 GDB 进程
pclose(fp);
//
}
bool get_symbol_from_elf(std::set<symbol> &ss, const char *path, size_t file_base_addr) {
bool get_symbol_from_elf(std::set<symbol> &ss, const char *path,
size_t file_base_addr) {
static int first_init = 0;
if (!first_init) {
@@ -450,7 +450,7 @@ bool get_symbol_from_elf(std::set<symbol> &ss, const char *path, size_t file_bas
if (str && strcmp(".symtab", str) == 0) { // .symtab section
symtab_sec = sec;
memcpy(&symtab_shdr, &shdr, sizeof(dynsym_shdr));
memcpy(&symtab_shdr, &shdr, sizeof(dynsym_shdr));
}
if (str && strcmp(".dynsym", str) == 0) { // .dynsym section
dynsym_sec = sec;
@@ -480,22 +480,13 @@ bool get_symbol_from_elf(std::set<symbol> &ss, const char *path, size_t file_bas
symbol_sections_ctx si;
memset(&si, 0, sizeof(si));
if (symtab_sec) {
get_symbols_in_section(&si.symtab, elf, symtab_sec, &symtab_shdr, is_reloc);
get_symbols_in_section(&si.symtab, elf, symtab_sec, &symtab_shdr, is_reloc);
} else {
if (hdr.e_type != ET_DYN) { // no shared object
// is_reloc = 1;
// printf("stripped, path: %s\n", path);
get_symbol_from_elf_gdb(ss, path, file_base_addr);
return true;
}
// Check if the file attribute contains "stripped"
// if (is_stripped(path))
// {
// printf("stripped, path: %s\n", path);
// get_symbol_from_elf_gdb(ss, path);
// return true;
// }
if (hdr.e_type != ET_DYN) { // no shared object
// printf("stripped, path: %s\n", path);
get_symbol_from_elf_gdb(ss, path, file_base_addr);
return true;
}
}
if (dynsym_sec) {
get_symbols_in_section(&si.symtab_in_dynsym, elf, dynsym_sec, &dynsym_shdr,
@@ -508,13 +499,6 @@ bool get_symbol_from_elf(std::set<symbol> &ss, const char *path, size_t file_bas
get_all_symbols(ss, &si, elf);
elf_end(elf);
// After getting all symbols from .symtab and .dynsym
// Dwarf *dw = dwarf_begin(fd, DWARF_C_READ);
// if (dw) {
// get_debug_symbols(ss, dw);
// dwarf_end(dw);
// }
close(fd);
return true;
}

View File

@@ -6,6 +6,7 @@
#include "symbol.h"
bool get_symbol_from_elf(std::set<symbol> &ss, const char *path, size_t file_base_addr);
bool get_symbol_from_elf(std::set<symbol> &ss, const char *path,
size_t file_base_addr);
#endif

View File

@@ -101,7 +101,7 @@ bool symbol_parser::load_pid_maps(int pid) {
bool symbol_parser::find_symbol_in_cache(int tgid, unsigned long addr,
std::string &symbol) {
std::map<int, std::map<unsigned long, std::string> >::const_iterator it_pid =
std::map<int, std::map<unsigned long, std::string>>::const_iterator it_pid =
symbols_cache.find(tgid);
if (it_pid != symbols_cache.end()) {
@@ -153,7 +153,7 @@ bool symbol_parser::get_symbol_info(int pid, symbol &sym, elf_file &file) {
bool symbol_parser::putin_symbol_cache(int tgid, unsigned long addr,
std::string &symbol) {
std::map<int, std::map<unsigned long, std::string> >::const_iterator it_pid =
std::map<int, std::map<unsigned long, std::string>>::const_iterator it_pid =
symbols_cache.find(tgid);
if (it_pid == symbols_cache.end()) {
@@ -188,8 +188,9 @@ bool search_symbol(const std::set<symbol> &ss, symbol &sym) {
return false;
}
bool symbol_parser::load_elf(pid_t pid, const elf_file &file, size_t file_base_addr) {
std::map<elf_file, std::set<symbol> >::iterator it;
bool symbol_parser::load_elf(pid_t pid, const elf_file &file,
size_t file_base_addr) {
std::map<elf_file, std::set<symbol>>::iterator it;
it = file_symbols.find(file);
std::set<symbol> tmp;
std::set<symbol> &syms = tmp;
@@ -206,7 +207,7 @@ bool symbol_parser::load_elf(pid_t pid, const elf_file &file, size_t file_base_a
bool symbol_parser::find_elf_symbol(symbol &sym, const elf_file &file, int pid,
int pid_ns) {
std::map<elf_file, std::set<symbol> >::iterator it;
std::map<elf_file, std::set<symbol>>::iterator it;
it = file_symbols.find(file);
std::set<symbol> ss;
// printf("search symbol1 0x%lx, base 0x%lx\n", sym.ip, sym.base);

View File

@@ -7,141 +7,140 @@
#define INVALID_ADDR ((size_t)(-1))
enum {
NATIVE_TYPE = 0,
JIT_TYPE = 1,
UNKNOWN = 2,
NATIVE_TYPE = 0,
JIT_TYPE = 1,
UNKNOWN = 2,
};
struct elf_file {
unsigned char elf_read_error;
size_t eh_frame_hdr_offset;
size_t fde_count;
size_t table_data;
std::string filename;
int type;
unsigned char elf_read_error;
size_t eh_frame_hdr_offset;
size_t fde_count;
size_t table_data;
std::string filename;
int type;
elf_file(const std::string &name) : filename(name), type(NATIVE_TYPE) {
elf_read_error = 0;
eh_frame_hdr_offset = 0;
fde_count = 0;
table_data = 0;
}
elf_file(const std::string &name) : filename(name), type(NATIVE_TYPE) {
elf_read_error = 0;
eh_frame_hdr_offset = 0;
fde_count = 0;
table_data = 0;
}
elf_file() :type(NATIVE_TYPE) {}
elf_file() : type(NATIVE_TYPE) {}
void reset(const std::string &name) {
filename = name;
elf_read_error = 0;
eh_frame_hdr_offset = 0;
fde_count = 0;
table_data = 0;
}
void reset(const std::string &name) {
filename = name;
elf_read_error = 0;
eh_frame_hdr_offset = 0;
fde_count = 0;
table_data = 0;
}
bool operator< (const elf_file &rhs) const {
return filename < rhs.filename;
}
bool operator<(const elf_file &rhs) const { return filename < rhs.filename; }
};
struct vma {
size_t start;
size_t end;
size_t offset;
size_t pc;
int type;
std::string name;
struct {
unsigned char elf_read_error;
size_t eh_frame_hdr_offset;
size_t fde_count;
size_t table_data;
};
size_t start;
size_t end;
size_t offset;
size_t pc;
int type;
std::string name;
struct {
unsigned char elf_read_error;
size_t eh_frame_hdr_offset;
size_t fde_count;
size_t table_data;
};
size_t map(size_t pc) {
// printf("pc: %lx, start: %lx, offset: %lx\n", pc, start, offset);
return pc - start + offset;
}
void set_type(int t) { type = t; }
vma(size_t s, size_t e, size_t o, const std::string &n)
:start(s), end(e), offset(o), pc(0), type(NATIVE_TYPE), name(n) {}
vma() : start(0), end(0), offset(0), pc(0), type(NATIVE_TYPE) {}
vma(size_t addr) : start(0), end(0), offset(0), pc(addr), type(NATIVE_TYPE) {}
bool operator<(const vma &vm) {
return vm.start < vm.pc;
}
vma &operator=(const vma &vm) {
if (this == &vm) {
return *this;
}
start = vm.start;
end = vm.end;
offset = vm.offset;
name = vm.name;
return *this;
size_t map(size_t pc) {
// printf("pc: %lx, start: %lx, offset: %lx\n", pc, start, offset);
return pc - start + offset;
}
void set_type(int t) { type = t; }
vma(size_t s, size_t e, size_t o, const std::string &n)
: start(s), end(e), offset(o), pc(0), type(NATIVE_TYPE), name(n) {}
vma() : start(0), end(0), offset(0), pc(0), type(NATIVE_TYPE) {}
vma(size_t addr) : start(0), end(0), offset(0), pc(addr), type(NATIVE_TYPE) {}
bool operator<(const vma &vm) { return vm.start < vm.pc; }
vma &operator=(const vma &vm) {
if (this == &vm) {
return *this;
}
start = vm.start;
end = vm.end;
offset = vm.offset;
name = vm.name;
return *this;
}
};
struct symbol {
size_t start;
size_t end;
size_t ip;
size_t base;
std::string name;
size_t start;
size_t end;
size_t ip;
size_t base;
std::string name;
symbol() :start(0), end(0), ip(0) , base(0) {}
symbol(size_t pc) :start(0), end(0), ip(pc) {}
symbol() : start(0), end(0), ip(0), base(0) {}
symbol(size_t pc) : start(0), end(0), ip(pc) {}
void reset(size_t va) { start = end = 0; ip = va; }
bool operator< (const symbol &sym) const {
return sym.ip < start;
}
void reset(size_t va) {
start = end = 0;
ip = va;
}
bool operator<(const symbol &sym) const { return sym.ip < start; }
bool operator> (const symbol &sym) const {
return sym.ip > end;
}
bool operator>(const symbol &sym) const { return sym.ip > end; }
};
class symbol_parser {
private:
typedef std::map<size_t, vma> proc_vma;
typedef std::map<size_t, vma> proc_vma;
std::map<elf_file, std::set<symbol>> file_symbols;
std::map<int, std::set<symbol>> java_symbols;
std::set<symbol> kernel_symbols;
std::map<int, proc_vma> machine_vma;
std::set<int> java_procs;
std::map<int, std::map<unsigned long, std::string>> symbols_cache;
std::map<elf_file, std::set<symbol> > file_symbols;
std::map<int, std::set<symbol> > java_symbols;
std::set<symbol> kernel_symbols;
std::map<int, proc_vma> machine_vma;
std::set<int> java_procs;
std::map<int, std::map<unsigned long, std::string> > symbols_cache;
public:
bool load_kernel();
std::set<int>& get_java_procs() { return java_procs; }
bool load_kernel();
std::set<int> &get_java_procs() { return java_procs; }
bool find_kernel_symbol(symbol &sym);
bool find_elf_symbol(symbol &sym, const elf_file &file, int pid, int pid_ns);
bool find_java_symbol(symbol &sym, int pid, int pid_ns);
bool find_kernel_symbol(symbol &sym);
bool find_elf_symbol(symbol &sym, const elf_file &file, int pid, int pid_ns);
bool find_java_symbol(symbol &sym, int pid, int pid_ns);
bool get_symbol_info(int pid, symbol &sym, elf_file &file);
bool get_symbol_info(int pid, symbol &sym, elf_file &file);
bool find_vma(pid_t pid, vma &vm);
vma* find_vma(pid_t pid, size_t pc);
void clear_symbol_info(int);
bool add_pid_maps(int pid, size_t start, size_t end, size_t offset, const char *name);
bool find_vma(pid_t pid, vma &vm);
vma *find_vma(pid_t pid, size_t pc);
void clear_symbol_info(int);
bool add_pid_maps(int pid, size_t start, size_t end, size_t offset,
const char *name);
bool find_symbol_in_cache(int tgid, unsigned long addr, std::string &symbol);
bool putin_symbol_cache(int tgid, unsigned long addr, std::string &symbol);
bool find_symbol_in_cache(int tgid, unsigned long addr, std::string &symbol);
bool putin_symbol_cache(int tgid, unsigned long addr, std::string &symbol);
void dump(void);
void dump(void);
private:
bool load_pid_maps(int pid);
bool load_elf(pid_t pid, const elf_file& file, size_t file_base_addr);
bool load_perf_map(int pid, int pid_ns);
bool load_pid_maps(int pid);
bool load_elf(pid_t pid, const elf_file &file, size_t file_base_addr);
bool load_perf_map(int pid, int pid_ns);
public:
int java_only;
int user_symbol;
int java_only;
int user_symbol;
};
extern symbol_parser g_symbol_parser;

View File

@@ -1,13 +1,13 @@
#include <errno.h>
#include <fcntl.h>
#include <fstream>
#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fstream>
#include <assert.h>
#include <stdio_ext.h>
#include <ctype.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
@@ -15,21 +15,20 @@
#include "ucli.h"
#include "unwind.h"
#define BUF_LEN 4096
#define WHITESPACE " \t\n\r"
#define WHITESPACE " \t\n\r"
#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
#define streq(a,b) (strcmp((a),(b)) == 0)
#define streq(a, b) (strcmp((a), (b)) == 0)
unsigned long run_in_host = 0;
using namespace std;
class pid_cmdline {
private:
private:
std::map<int, std::string> cmdlines;
public:
public:
void clear(void);
std::string &get_pid_cmdline(int pid);
};
@@ -71,14 +70,14 @@ long diag_call_ioctl(unsigned long request, unsigned long arg) {
fd = open(DEVICE, O_RDWR, 0);
if (fd < 0) {
printf("open %s error,try to open %s\n", DEVICE, DEVICE_BAK);
fd = open(DEVICE_BAK, O_RDWR, 0);
if (fd < 0) {
printf("open %s error!\n", DEVICE_BAK);
return EEXIST;
} else {
printf("open %s success!\n", DEVICE_BAK);
}
printf("open %s error,try to open %s\n", DEVICE, DEVICE_BAK);
fd = open(DEVICE_BAK, O_RDWR, 0);
if (fd < 0) {
printf("open %s error!\n", DEVICE_BAK);
return EEXIST;
} else {
printf("open %s success!\n", DEVICE_BAK);
}
}
ret = ioctl(fd, request, arg);
@@ -94,7 +93,7 @@ err:
static int unwind_frame_callback(struct unwind_entry *entry, void *arg) {
symbol sym;
std::string symbol; // Use std::string instead of string
std::string symbol; // Use std::string instead of string
elf_file file;
sym.reset(entry->ip);
@@ -135,9 +134,12 @@ void extract_variant_buffer(char *buf, unsigned int len,
while (pos < len) {
head = (struct diag_variant_buffer_head *)(buf + pos);
if (pos + sizeof(struct diag_variant_buffer_head) >= len) break;
if (head->magic != DIAG_VARIANT_BUFFER_HEAD_MAGIC_SEALED) break;
if (head->len < sizeof(struct diag_variant_buffer_head)) break;
if (pos + sizeof(struct diag_variant_buffer_head) >= len)
break;
if (head->magic != DIAG_VARIANT_BUFFER_HEAD_MAGIC_SEALED)
break;
if (head->len < sizeof(struct diag_variant_buffer_head))
break;
rec = (void *)(buf + pos + sizeof(struct diag_variant_buffer_head));
rec_len = head->len - sizeof(struct diag_variant_buffer_head);
@@ -171,29 +173,28 @@ void diag_printf_raw_stack(int pid, int ns_pid, const char *comm,
fflush(stdout);
}
// 根据 sys_task 取值返回对应的字符串
static const char *sys_task_str(int sys_task) {
switch (sys_task) {
case 0:
return "USER_TASK";
case 1:
return "SYSTEM_TASK";
case 2:
return "IDLE_TASK";
default:
return "UNKNOWN_TASK";
case 0:
return "USER_TASK";
case 1:
return "SYSTEM_TASK";
case 2:
return "IDLE_TASK";
default:
return "UNKNOWN_TASK";
}
}
static const char *user_mode_str(int user_mode) {
switch (user_mode) {
case 1:
return "USER MODE";
case 0:
return "SYSTEM MODE";
default:
return "UNKNOWN MODE";
case 1:
return "USER MODE";
case 0:
return "SYSTEM MODE";
default:
return "UNKNOWN MODE";
}
}
@@ -203,9 +204,9 @@ static const char *user_mode_str(int user_mode) {
// #define TASK_UNINTERRUPTIBLE 0x0002 // 等待事件阻塞 不可信号唤醒
// #define __TASK_STOPPED 0x0004 // 暂停执行
// #define __TASK_TRACED 0x0008 //调试状态
// #define TASK_PARKED 0x0040 // parked 状态,暂停执行 保留在 cpu 但不被调度
// #define TASK_DEAD 0x0080 // dead
// #define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)
// #define TASK_PARKED 0x0040 // parked 状态,暂停执行 保留在 cpu
// 但不被调度 #define TASK_DEAD 0x0080 // dead #define
// TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)
// #define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED)
// #define TASK_IDLE (TASK_UNINTERRUPTIBLE | TASK_NOLOAD)
// static const char *state_str(int __state){
@@ -215,48 +216,61 @@ static const char *user_mode_str(int user_mode) {
#include <string>
#include <vector>
#define TASK_RUNNING 0x0000
#define TASK_INTERRUPTIBLE 0x0001
#define TASK_UNINTERRUPTIBLE 0x0002
#define __TASK_STOPPED 0x0004
#define __TASK_TRACED 0x0008
#define TASK_PARKED 0x0040
#define TASK_DEAD 0x0080
#define TASK_WAKEKILL 0x0100
#define TASK_NOLOAD 0x0200
#define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)
#define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED)
#define TASK_IDLE (TASK_UNINTERRUPTIBLE | TASK_NOLOAD)
#define TASK_RUNNING 0x0000
#define TASK_INTERRUPTIBLE 0x0001
#define TASK_UNINTERRUPTIBLE 0x0002
#define __TASK_STOPPED 0x0004
#define __TASK_TRACED 0x0008
#define TASK_PARKED 0x0040
#define TASK_DEAD 0x0080
#define TASK_WAKEKILL 0x0100
#define TASK_NOLOAD 0x0200
#define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)
#define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED)
#define TASK_IDLE (TASK_UNINTERRUPTIBLE | TASK_NOLOAD)
std::string state_str(int __state){
std::vector<std::string> states;
std::string state_str(int __state) {
std::vector<std::string> states;
if (__state == TASK_RUNNING) states.push_back("TASK_RUNNING");
// if (__state & TASK_RUNNING) states.push_back("TASK_RUNNING");
if (__state & TASK_INTERRUPTIBLE) states.push_back("TASK_INTERRUPTIBLE");
if (__state & TASK_UNINTERRUPTIBLE) states.push_back("TASK_UNINTERRUPTIBLE");
if (__state & __TASK_STOPPED) states.push_back("__TASK_STOPPED");
if (__state & __TASK_TRACED) states.push_back("__TASK_TRACED");
if (__state & TASK_PARKED) states.push_back("TASK_PARKED");
if (__state & TASK_DEAD) states.push_back("TASK_DEAD");
if (__state == TASK_KILLABLE) states.push_back("TASK_KILLABLE");
if (__state == TASK_STOPPED) states.push_back("TASK_STOPPED");
if (__state == TASK_IDLE) states.push_back("TASK_IDLE");
if (__state == TASK_RUNNING)
states.push_back("TASK_RUNNING");
// if (__state & TASK_RUNNING) states.push_back("TASK_RUNNING");
if (__state & TASK_INTERRUPTIBLE)
states.push_back("TASK_INTERRUPTIBLE");
if (__state & TASK_UNINTERRUPTIBLE)
states.push_back("TASK_UNINTERRUPTIBLE");
if (__state & __TASK_STOPPED)
states.push_back("__TASK_STOPPED");
if (__state & __TASK_TRACED)
states.push_back("__TASK_TRACED");
if (__state & TASK_PARKED)
states.push_back("TASK_PARKED");
if (__state & TASK_DEAD)
states.push_back("TASK_DEAD");
if (__state == TASK_KILLABLE)
states.push_back("TASK_KILLABLE");
if (__state == TASK_STOPPED)
states.push_back("TASK_STOPPED");
if (__state == TASK_IDLE)
states.push_back("TASK_IDLE");
std::string result;
for (const auto& state : states) {
if (!result.empty()) result += " | ";
result += state;
}
std::string result;
for (const auto &state : states) {
if (!result.empty())
result += " | ";
result += state;
}
return result;
return result;
}
void printk_task_brief(task_detail *detail) {
printf(" TASK INFO: %s [%s / %s], PID: %d / %d\n", sys_task_str(detail->sys_task) ,detail->cgroup_buf, detail->comm, detail->tgid,
detail->pid);
// printf(" TASK STATE: type: %s, state: %s, state %d\n", sys_task_str(detail->sys_task), state_str(detail->state).c_str(),
// detail->state);
printf(" TASK INFO: %s [%s / %s], PID: %d / %d\n",
sys_task_str(detail->sys_task), detail->cgroup_buf, detail->comm,
detail->tgid, detail->pid);
// printf(" TASK STATE: type: %s, state: %s, state %d\n",
// sys_task_str(detail->sys_task), state_str(detail->state).c_str(),
// detail->state);
}
void diag_printf_kern_stack(kern_stack_detail *kern_stack) {
@@ -284,7 +298,8 @@ void diag_printf_proc_chains(proc_chains_detail *proc_chains) {
printf(" PROC CHAINS:\n");
for (i = 0; i < PROCESS_CHAINS_COUNT; i++) {
if (proc_chains->chains[i][0] == 0) break;
if (proc_chains->chains[i][0] == 0)
break;
if (proc_chains->full_argv[i] == 0 && detail) {
string cmdline = pid_cmdline.get_pid_cmdline(proc_chains->tgid[i]);
if (cmdline.length() > 0)
@@ -300,155 +315,151 @@ void diag_printf_proc_chains(proc_chains_detail *proc_chains) {
}
int is_pid_1_has_environ(const char *field) {
bool done = false;
FILE *f = NULL;
int r = 0;
size_t l;
bool done = false;
FILE *f = NULL;
int r = 0;
size_t l;
assert(field);
assert(field);
f = fopen("/proc/1/environ", "re");
if (!f)
return 0;
f = fopen("/proc/1/environ", "re");
if (!f)
return 0;
(void) __fsetlocking(f, FSETLOCKING_BYCALLER);
(void)__fsetlocking(f, FSETLOCKING_BYCALLER);
l = strlen(field);
l = strlen(field);
do {
char line[BUF_LEN];
size_t i;
do {
char line[BUF_LEN];
size_t i;
for (i = 0; i < sizeof(line)-1; i++) {
int c;
for (i = 0; i < sizeof(line) - 1; i++) {
int c;
c = getc(f);
if ((c == EOF)) {
done = true;
break;
} else if (c == 0)
break;
c = getc(f);
if ((c == EOF)) {
done = true;
break;
} else if (c == 0)
break;
line[i] = c;
}
line[i] = 0;
line[i] = c;
}
line[i] = 0;
if (strneq(line, field, l) && line[l] == '=') {
r = 1;
goto out;
}
if (strneq(line, field, l) && line[l] == '=') {
r = 1;
goto out;
}
} while (!done);
} while (!done);
out:
fclose(f);
return r;
fclose(f);
return r;
}
enum {
RUN_IN_HOST = 0,
RUN_IN_CONTAINER
};
enum { RUN_IN_HOST = 0, RUN_IN_CONTAINER };
int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field) {
char status[BUF_LEN] = {0};
char *t, *f;
size_t len;
int r;
int get_proc_field(const char *filename, const char *pattern,
const char *terminator, char **field) {
char status[BUF_LEN] = {0};
char *t, *f;
size_t len;
int r;
assert(terminator);
assert(filename);
assert(pattern);
assert(field);
assert(terminator);
assert(filename);
assert(pattern);
assert(field);
int fd = open(filename, O_RDONLY);
if (fd < 0)
return -errno;
int fd = open(filename, O_RDONLY);
if (fd < 0)
return -errno;
r = read(fd, &status, BUF_LEN - 1);
if (r < 0)
return r;
r = read(fd, &status, BUF_LEN - 1);
if (r < 0)
return r;
t = status;
t = status;
do {
bool pattern_ok;
do {
bool pattern_ok;
do {
t = strstr(t, pattern);
if (!t)
return -ENOENT;
do {
t = strstr(t, pattern);
if (!t)
return -ENOENT;
/* Check that pattern occurs in beginning of line. */
pattern_ok = (t == status || t[-1] == '\n');
/* Check that pattern occurs in beginning of line. */
pattern_ok = (t == status || t[-1] == '\n');
t += strlen(pattern);
t += strlen(pattern);
} while (!pattern_ok);
} while (!pattern_ok);
t += strspn(t, " \t");
if (!*t)
return -ENOENT;
t += strspn(t, " \t");
if (!*t)
return -ENOENT;
} while (*t != ':');
} while (*t != ':');
t++;
t++;
if (*t) {
t += strspn(t, " \t");
if (*t) {
t += strspn(t, " \t");
/* Also skip zeros, because when this is used for
* capabilities, we don't want the zeros. This way the
* same capability set always maps to the same string,
* irrespective of the total capability set size. For
* other numbers it shouldn't matter. */
t += strspn(t, "0");
/* Back off one char if there's nothing but whitespace
and zeros */
if (!*t || isspace(*t))
t--;
}
/* Also skip zeros, because when this is used for
* capabilities, we don't want the zeros. This way the
* same capability set always maps to the same string,
* irrespective of the total capability set size. For
* other numbers it shouldn't matter. */
t += strspn(t, "0");
/* Back off one char if there's nothing but whitespace
and zeros */
if (!*t || isspace(*t))
t--;
}
len = strcspn(t, terminator);
len = strcspn(t, terminator);
f = strndup(t, len);
if (!f)
return -ENOMEM;
f = strndup(t, len);
if (!f)
return -ENOMEM;
*field = f;
return 0;
*field = f;
return 0;
}
static int detect_container_by_pid_2(void) {
char *s = NULL;
int r;
char *s = NULL;
int r;
r = get_proc_field("/proc/2/status", "PPid", WHITESPACE, &s);
if (r >= 0) {
if (streq(s, "0"))
r = RUN_IN_HOST;
else
r = RUN_IN_CONTAINER;
} else if (r == -ENOENT)
r = RUN_IN_CONTAINER;
else {
printf("Failed to read /proc/2/status: %d\n", r);
r = RUN_IN_HOST;
}
r = get_proc_field("/proc/2/status", "PPid", WHITESPACE, &s);
if (r >= 0) {
if (streq(s, "0"))
r = RUN_IN_HOST;
else
r = RUN_IN_CONTAINER;
} else if (r == -ENOENT)
r = RUN_IN_CONTAINER;
else {
printf("Failed to read /proc/2/status: %d\n", r);
r = RUN_IN_HOST;
}
free(s);
return r;
free(s);
return r;
}
int check_in_host(void)
{
int r;
int check_in_host(void) {
int r;
if (is_pid_1_has_environ("container"))
r = RUN_IN_CONTAINER;
else
r = detect_container_by_pid_2();
if (is_pid_1_has_environ("container"))
r = RUN_IN_CONTAINER;
else
r = detect_container_by_pid_2();
return r == RUN_IN_HOST;
return r == RUN_IN_HOST;
}

View File

@@ -114,8 +114,7 @@ static int task_info_extract(void *buf, unsigned int len, void *) {
.name, // Assuming name is a null-terminated string
vm_record->threshold_record[i].ptr,
vm_record->threshold_record[i].threshold,
vm_record->threshold_record[i].true_value
);
vm_record->threshold_record[i].true_value);
}
break;
case VARIABLE_MONITOR_TASK_TYPE:
@@ -126,7 +125,7 @@ static int task_info_extract(void *buf, unsigned int len, void *) {
printf("##CGROUP:[%s] %d [%03d] [%s] state: %d\n",
tsk_info->task.cgroup_buf, tsk_info->task.pid, seq,
state_str(tsk_info->task.state).c_str(),tsk_info->task.state);
state_str(tsk_info->task.state).c_str(), tsk_info->task.state);
printk_task_brief(&tsk_info->task);
// diag_printf_raw_stack(tsk_info->task.tgid, tsk_info->task.container_tgid,
@@ -141,12 +140,14 @@ static int task_info_extract(void *buf, unsigned int len, void *) {
// diag_printf_kern_stack(&tsk_info->kern_stack);
// system task no need print raw_stack
if (tsk_info->task.sys_task == 1){
diag_printf_kern_stack(&tsk_info->kern_stack);
}else{
diag_printf_raw_stack(run_in_host ? tsk_info->task.tgid : tsk_info->task.container_tgid,
tsk_info->task.container_tgid, tsk_info->task.comm, &tsk_info->raw_stack);
diag_printf_kern_stack(&tsk_info->kern_stack);
if (tsk_info->task.sys_task == 1) {
diag_printf_kern_stack(&tsk_info->kern_stack);
} else {
diag_printf_raw_stack(run_in_host ? tsk_info->task.tgid
: tsk_info->task.container_tgid,
tsk_info->task.container_tgid, tsk_info->task.comm,
&tsk_info->raw_stack);
diag_printf_kern_stack(&tsk_info->kern_stack);
}
printf("#* 0xffffffffffffff %s (UNKNOWN)\n", tsk_info->task.comm);
@@ -161,17 +162,19 @@ static int task_info_extract(void *buf, unsigned int len, void *) {
printf("##CGROUP:[%s] %d [%03d] [%s] state: %d\n",
tsk_info_system->task.cgroup_buf, tsk_info_system->task.pid, seq,
state_str(tsk_info_system->task.state).c_str(),tsk_info_system->task.state);
state_str(tsk_info_system->task.state).c_str(),
tsk_info_system->task.state);
printk_task_brief(&tsk_info_system->task);
// system task no need print raw_stack
diag_printf_kern_stack(&tsk_info_system->kern_stack);
printf("#* 0xffffffffffffff %s (UNKNOWN)\n", tsk_info_system->task.comm);
printf("#* 0xffffffffffffff %s (UNKNOWN)\n",
tsk_info_system->task.comm);
// diag_printf_proc_chains(&tsk_info_system->proc_chains);
printf("##\n");
break;
default:
break;
}
@@ -248,7 +251,7 @@ int main(int argc, char *argv[]) {
run_in_host = check_in_host();
printf("run_in_host: %d\n", run_in_host);
for (int i = 0; i < argc; i++){
for (int i = 0; i < argc; i++) {
printf("argv[%d]: %s\n", i, argv[i]);
}

View File

@@ -1,10 +1,10 @@
#ifndef UAPI_H
#define UAPI_H
#include <asm/ptrace.h> // struct pt_regs
#include <asm/ptrace.h> // struct pt_regs
#include <sys/types.h>
#include <cstddef> // size_t
#include <cstddef> // size_t
#include <stdlib.h>
#include <string>
@@ -20,25 +20,25 @@
#define DEVICE "/dev/variable_monitor"
#define DEVICE_BAK "/host/dev/variable_monitor"
#define CGROUP_NAME_LEN 32 // max length of cgroup name
#define TASK_COMM_LEN 16 // max length of task name
#define CGROUP_NAME_LEN 32 // max length of cgroup name
#define TASK_COMM_LEN 16 // max length of task name
#define BACKTRACE_DEPTH 30 // max depth of backtrace
#define BACKTRACE_DEPTH 30 // max depth of backtrace
#define PROCESS_CHAINS_COUNT 10 // max count of process chains
#define PROCESS_ARGV_LEN 128 // max length of process argv
#define PROCESS_CHAINS_COUNT 10 // max count of process chains
#define PROCESS_ARGV_LEN 128 // max length of process argv
#define MAX_NAME_LEN (127) // max name length
#define TIMER_MAX_WATCH_NUM (32) // A timer max watch number at once time
#define MAX_NAME_LEN (127) // max name length
#define TIMER_MAX_WATCH_NUM (32) // A timer max watch number at once time
#define DIAG_USER_STACK_SIZE (16 * 1024)
typedef struct {
pid_t task_id; // current process id
char name[MAX_NAME_LEN + 1]; // name
void *ptr; // virtual address
long long threshold; // threshold value
long long true_value; // target true value
pid_t task_id; // current process id
char name[MAX_NAME_LEN + 1]; // name
void *ptr; // virtual address
long long threshold; // threshold value
long long true_value; // target true value
} threshold;
typedef struct {
@@ -92,9 +92,9 @@ typedef struct {
} raw_stack_detail;
typedef struct {
unsigned int full_argv[PROCESS_CHAINS_COUNT]; //
char chains[PROCESS_CHAINS_COUNT][PROCESS_ARGV_LEN]; // process chains argv
unsigned int tgid[PROCESS_CHAINS_COUNT]; // process chains tgid
unsigned int full_argv[PROCESS_CHAINS_COUNT]; //
char chains[PROCESS_CHAINS_COUNT][PROCESS_ARGV_LEN]; // process chains argv
unsigned int tgid[PROCESS_CHAINS_COUNT]; // process chains tgid
} proc_chains_detail;
// most important struct
@@ -102,10 +102,10 @@ typedef struct {
int et_type;
unsigned long id;
unsigned long long tv;
task_detail task; // brief
task_detail task; // brief
// user_stack_detail user_stack; // user stack
kern_stack_detail kern_stack; // kernel stack
proc_chains_detail proc_chains; // process chains argv
kern_stack_detail kern_stack; // kernel stack
proc_chains_detail proc_chains; // process chains argv
raw_stack_detail raw_stack;
} variable_monitor_task;
@@ -113,8 +113,8 @@ typedef struct {
int et_type;
unsigned long id;
unsigned long long tv;
task_detail task; // brief
kern_stack_detail kern_stack; // kernel stack
task_detail task; // brief
kern_stack_detail kern_stack; // kernel stack
} variable_monitor_task_system;
#define DIAG_VARIANT_BUFFER_HEAD_MAGIC_SEALED 197612031122

View File

@@ -20,16 +20,19 @@ static std::string unknow_symbol("UNKNOWN");
// }
// if (g_symbol_parser.get_symbol_info(entry->pid, sym, file)) {
// if (g_symbol_parser.find_elf_symbol(sym, file, entry->pid, entry->pid_ns)) {
// if (g_symbol_parser.find_elf_symbol(sym, file, entry->pid,
// entry->pid_ns)) {
// printf("#~ 0x%lx %s ([symbol])\n", entry->ip, sym.name.c_str());
// g_symbol_parser.putin_symbol_cache(entry->pid, entry->ip, sym.name);
// } else {
// printf("#~ 0x%lx %s ([symbol])\n", entry->ip, "(unknown)[symbol]");
// g_symbol_parser.putin_symbol_cache(entry->pid, entry->ip, unknow_symbol);
// printf("#~ 0x%lx %s ([symbol])\n", entry->ip,
// "(unknown)[symbol]"); g_symbol_parser.putin_symbol_cache(entry->pid,
// entry->ip, unknow_symbol);
// }
// } else {
// printf("#~ 0x%lx %s ([symbol])\n", entry->ip, "(unknown)[vma,elf]");
// g_symbol_parser.putin_symbol_cache(entry->pid, entry->ip, unknow_symbol);
// printf("#~ 0x%lx %s ([symbol])\n", entry->ip,
// "(unknown)[vma,elf]"); g_symbol_parser.putin_symbol_cache(entry->pid,
// entry->ip, unknow_symbol);
// }
// return 0;
@@ -39,7 +42,8 @@ static std::string unknow_symbol("UNKNOWN");
*/
static int reg_value(unw_word_t *valp, struct regs_dump *regs, int id) {
/* we only support 3 registers. RIP, RSP and RBP */
if (id < 0 || id > 2) return -EINVAL;
if (id < 0 || id > 2)
return -EINVAL;
*valp = regs->regs[id];
return 0;
@@ -76,12 +80,13 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb,
while (!ret && (unw_step(&c) > 0)) {
unw_word_t ip;
unw_get_reg(&c, UNW_REG_IP, &ip); // get IP from current step;
unw_get_reg(&c, UNW_REG_IP, &ip); // get IP from current step;
cb_arg->arg = &c;
ret = entry(ip, ui->pid, ui->pid_ns, cb, cb_arg);
loops++;
if (loops >= 50) break;
if (loops >= 50)
break;
}
unw_destroy_addr_space(addr_space);
@@ -99,35 +104,16 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, symbol_parser *sp,
};
int ret;
if (!data->user_regs.regs) return -EINVAL;
if (!data->user_regs.regs)
return -EINVAL;
ret = reg_value(&ip, &data->user_regs, PERF_REG_IP);
if (ret) return ret;
if (ret)
return ret;
ret = entry(ip, pid, pid_ns, cb, arg);
if (ret) return -ENOMEM;
if (ret)
return -ENOMEM;
return get_entries(&ui, cb, arg);
}
// void diag_printf_raw_stack(int pid, int ns_pid, const char *comm,
// raw_stack_detail *raw_stack, int attach){
// struct perf_sample stack_sample;
// entry_cb_arg_t unwind_arg;
// static u64 regs_buf[3];
// printf("##C++ pid %d\n", pid);
// printf(" 用户态堆栈SP%lx, BP:%lx, IP:%lx\n", raw_stack->sp,
// raw_stack->bp, raw_stack->ip);
// stack_sample.user_stack.offset = 0;
// stack_sample.user_stack.size = raw_stack->stack_size;
// stack_sample.user_stack.data = (char *)&raw_stack->stack[0];
// stack_sample.user_regs.regs = regs_buf;
// stack_sample.user_regs.regs[PERF_REG_IP] = raw_stack->ip;
// stack_sample.user_regs.regs[PERF_REG_SP] = raw_stack->sp;
// stack_sample.user_regs.regs[PERF_REG_BP] = raw_stack->bp;
// unwind__get_entries(unwind_frame_callback, &unwind_arg, &g_symbol_parser, pid,
// ns_pid, &stack_sample);
// fflush(stdout);
// }
}

View File

@@ -103,7 +103,8 @@ struct unwind_info {
};
// extern "C" void diag_printf_raw_stack(int pid, int ns_pid, const char *comm,
// raw_stack_detail *raw_stack, int attach);
// raw_stack_detail *raw_stack, int
// attach);
int unwind__get_entries(unwind_entry_cb_t cb, void *arg, symbol_parser *sp,
int pid, int pid_ns, struct perf_sample *data);
#endif /* __UNWIND_H */