| 3297 | } |
| 3298 | |
| 3299 | MEM_NO_INSTRUMENT static const char *tryAddr2lineResolve(void *addr) |
| 3300 | { |
| 3301 | struct protect |
| 3302 | { |
| 3303 | ~protect() |
| 3304 | { |
| 3305 | exe_path_initialized = false; |
| 3306 | memset(exe_path, 0, sizeof(exe_path)); |
| 3307 | } |
| 3308 | char exe_path[1024] = {0}; |
| 3309 | bool exe_path_initialized = false; |
| 3310 | }; |
| 3311 | |
| 3312 | static protect p; |
| 3313 | char *exe_path = p.exe_path; |
| 3314 | bool &exe_path_initialized = p.exe_path_initialized; |
| 3315 | |
| 3316 | if (!exe_path_initialized) |
| 3317 | { |
| 3318 | ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1); |
| 3319 | if (len > 0) |
| 3320 | { |
| 3321 | exe_path[len] = '\0'; |
| 3322 | exe_path_initialized = true; |
| 3323 | } |
| 3324 | else |
| 3325 | { |
| 3326 | return nullptr; |
| 3327 | } |
| 3328 | } |
| 3329 | |
| 3330 | char cmd[2048]; |
| 3331 | snprintf(cmd, sizeof(cmd), "addr2line -f -C -e %s %p 2>/dev/null", exe_path, addr); |
| 3332 | |
| 3333 | FILE *fp = popen(cmd, "r"); |
| 3334 | if (!fp) |
| 3335 | return nullptr; |
| 3336 | |
| 3337 | char function_name[512] = {0}; |
| 3338 | char file_location[512] = {0}; |
| 3339 | |
| 3340 | if (fgets(function_name, sizeof(function_name), fp)) |
| 3341 | { |
| 3342 | char *newline = strchr(function_name, '\n'); |
| 3343 | if (newline) |
| 3344 | *newline = '\0'; |
| 3345 | |
| 3346 | if (fgets(file_location, sizeof(file_location), fp)) |
| 3347 | { |
| 3348 | newline = strchr(file_location, '\n'); |
| 3349 | if (newline) |
| 3350 | *newline = '\0'; |
| 3351 | |
| 3352 | if (strcmp(function_name, "??") != 0) |
| 3353 | { |
| 3354 | const char *filename = strrchr(file_location, '/'); |
| 3355 | filename = filename ? filename + 1 : file_location; |
| 3356 |
no test coverage detected