ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
system.c File Reference

🐧 Linux system utilities and backtrace symbol resolution More...

Go to the source code of this file.

Functions

int get_binary_file_address_offsets (const void *addr, platform_binary_match_t *matches, int max_matches)
 Get binary that contains address on Linux via /proc/self/maps.
 

Detailed Description

🐧 Linux system utilities and backtrace symbol resolution

Definition in file linux/system.c.

Function Documentation

◆ get_binary_file_address_offsets()

int get_binary_file_address_offsets ( const void *  addr,
platform_binary_match_t *  matches,
int  max_matches 
)

Get binary that contains address on Linux via /proc/self/maps.

Scans /proc/self/maps to find which loaded binary (exe or .so) contains the given runtime address. Returns the file offset within that binary, which is passed to llvm-symbolizer for symbol resolution.

Parameters
addrRuntime address from backtrace
matchesOutput array for matches (path, offset, is_project_lib)
max_matchesMaximum number of matches to store
Returns
Number of matches found (0, 1, or rarely 2)

Definition at line 26 of file linux/system.c.

26 {
27 int count = 0;
28 uintptr_t addr_int = (uintptr_t)addr;
29
30 FILE *maps = fopen("/proc/self/maps", "r");
31 if (!maps) {
32 return 0;
33 }
34
35 char line[512];
36 while (fgets(line, sizeof(line), maps) && count < max_matches) {
37 uintptr_t start, end, offset;
38 char perms[5], device[10], path[PLATFORM_MAX_PATH_LENGTH];
39 unsigned long inode;
40
41 // Parse: start-end perms offset device inode path
42 // Example: 7f3a2b1c0000-7f3a2b1c1000 r-xp 00000000 08:02 12345678 /usr/lib/libsodium.so.23
43 int parsed = sscanf(line, "%lx-%lx %4s %lx %9s %lu", &start, &end, perms, &offset, device, &inode);
44
45 if (parsed < 6) {
46 continue; // Incomplete line
47 }
48
49 // Skip lines without executable flag
50 if (perms[2] != 'x') {
51 continue;
52 }
53
54 // Extract path more robustly by searching for the last whitespace-separated token
55 // /proc/self/maps format: start-end perms offset device inode [path]
56 // The path is optional and starts after the inode field
57 path[0] = '\0';
58
59 // Find the last whitespace and take everything after it as the path
60 // This is more robust than trying to count fields
61 int line_len = strlen(line);
62 int path_start = -1;
63
64 // Scan from the end backwards to find the last non-whitespace character
65 for (int i = line_len - 1; i >= 0; i--) {
66 if (line[i] != ' ' && line[i] != '\t' && line[i] != '\n' && line[i] != '\r') {
67 // Found a non-whitespace char, now find the start of this token
68 path_start = i;
69 while (path_start > 0 && line[path_start - 1] != ' ' && line[path_start - 1] != '\t') {
70 path_start--;
71 }
72 break;
73 }
74 }
75
76 if (path_start > 0 && line[path_start - 1] != '\0') {
77 // Extract the path starting from path_start
78 strncpy(path, &line[path_start], PLATFORM_MAX_PATH_LENGTH - 1);
79 path[PLATFORM_MAX_PATH_LENGTH - 1] = '\0';
80 // Remove trailing whitespace
81 int path_len = strlen(path);
82 while (path_len > 0 && (path[path_len - 1] == '\n' || path[path_len - 1] == '\r')) {
83 path[--path_len] = '\0';
84 }
85 }
86
87 // Check if address falls within this segment
88 if (perms[2] == 'x' && path[0] == '/') {
89 if (addr_int >= start && addr_int < end) {
90 strncpy(matches[count].path, path, PLATFORM_MAX_PATH_LENGTH - 1);
91 matches[count].path[PLATFORM_MAX_PATH_LENGTH - 1] = '\0';
92 matches[count].file_offset = (addr_int - start) + offset;
93 count++;
94 }
95 }
96 }
97
98 fclose(maps);
99 return count;
100}
#define PLATFORM_MAX_PATH_LENGTH
Definition system.c:64

References PLATFORM_MAX_PATH_LENGTH.