Skip to content

Commit 4b69d03

Browse files
committed
cc: support versioned SONAME in shared library resolution
bcc_procutils_which_so() and related helpers previously handled only short library names (e.g. "ssl"), constructing "lib%s.so" and selecting the first cache entry from /etc/ld.so.cache. This change makes to recognize versioned SONAME fragments that contain ".so.x" (e.g. "ssl.so.3.5.3", "crypto.so.3"), treating such names as exact matches instead of appending another ".so". This enables correct resolution of versioned libraries (e.g. libssl.so.3 vs libssl.so.59) while maintaining compatibility with existing short-name lookups. This improves correctness on systems where multiple SONAME variants coexist in the cache (e.g. OpenSSL vs LibreSSL). Related: #5412 Signed-off-by: Hoyeon Lee <[email protected]>
1 parent b63d7e3 commit 4b69d03

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

docs/reference_guide.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1723,7 +1723,7 @@ By default `pid` is set to -1, indicating the `uprobe` will be attached to all p
17231723
For libraries, the uprobe will attach to the version of the library used by the process if `pid` was given.
17241724
For how `pid` is used, see examples in [funcinterval](https://github.com/iovisor/bcc/blob/78423e1667db202012bbb032c567589175a2796c/tools/funcinterval.py#L155-L156).
17251725

1726-
Libraries can be given in the name argument without the lib prefix, or with the full path (/usr/lib/...). Binaries can be given only with the full path (/bin/sh).
1726+
Libraries can be given in the name argument without the lib prefix, optionally with a versioned SONAME (c.so.6), or with the full path (/usr/lib/...). Binaries can be given only with the full path (/bin/sh).
17271727

17281728
For example:
17291729

src/cc/bcc_proc.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,8 @@ static bool which_so_in_process(const char* libname, int pid, char* libpath) {
469469
int ret, found = false;
470470
char endline[4096], *mapname = NULL, *newline;
471471
char mappings_file[128];
472-
const size_t search_len = strlen(libname) + strlen("/lib.");
472+
const bool has_so = strstr(libname, ".so");
473+
const size_t search_len = strlen(libname) + strlen(has_so ? "/lib" : "/lib.");
473474
char search1[search_len + 1];
474475
char search2[search_len + 1];
475476

@@ -478,8 +479,13 @@ static bool which_so_in_process(const char* libname, int pid, char* libpath) {
478479
if (!fp)
479480
return NULL;
480481

481-
snprintf(search1, search_len + 1, "/lib%s.", libname);
482-
snprintf(search2, search_len + 1, "/lib%s-", libname);
482+
if (has_so) {
483+
snprintf(search1, search_len + 1, "/lib%s", libname);
484+
search2[0] = '\0';
485+
} else {
486+
snprintf(search1, search_len + 1, "/lib%s.", libname);
487+
snprintf(search2, search_len + 1, "/lib%s-", libname);
488+
}
483489

484490
do {
485491
ret = fscanf(fp, "%*x-%*x %*s %*x %*s %*d");
@@ -494,7 +500,7 @@ static bool which_so_in_process(const char* libname, int pid, char* libpath) {
494500
while (isspace(mapname[0])) mapname++;
495501

496502
if (strstr(mapname, ".so") && (strstr(mapname, search1) ||
497-
strstr(mapname, search2))) {
503+
(!has_so && strstr(mapname, search2)))) {
498504
const size_t mapnamelen = strlen(mapname);
499505
if (mapnamelen >= PATH_MAX) {
500506
fprintf(stderr, "Found mapped library path is too long\n");
@@ -511,7 +517,8 @@ static bool which_so_in_process(const char* libname, int pid, char* libpath) {
511517
}
512518

513519
static bool which_so_in_ldconfig_cache(const char* libname, char* libpath) {
514-
const size_t soname_len = strlen(libname) + strlen("lib.so");
520+
const bool has_so = strstr(libname, ".so");
521+
const size_t soname_len = strlen(libname) + strlen(has_so ? "lib" : "lib.so");
515522
char soname[soname_len + 1];
516523
int i;
517524

@@ -523,7 +530,7 @@ static bool which_so_in_ldconfig_cache(const char* libname, char* libpath) {
523530
return false;
524531
}
525532

526-
snprintf(soname, soname_len + 1, "lib%s.so", libname);
533+
snprintf(soname, sizeof(soname), has_so ? "lib%s" : "lib%s.so", libname);
527534

528535
for (i = 0; i < lib_cache_count; ++i) {
529536
if (!strncmp(lib_cache[i].libname, soname, soname_len) &&

0 commit comments

Comments
 (0)