Skip to content

Commit

Permalink
Merge pull request #217 from P403n1x87/fix/container-support
Browse files Browse the repository at this point in the history
fix(linux): improved container support
  • Loading branch information
P403n1x87 authored Apr 1, 2024
2 parents 5303860 + 0f8e7d7 commit 4559915
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 27 deletions.
2 changes: 2 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
2024-xx-xx v3.6.1

Improve support for Python processes running in containers.

Bugfix: fixed a bug with the MOJO binary format that caused the line end
position to wrongly be set to a non-zero value for CPython < 3.11, where line
end information is not actually available.
Expand Down
23 changes: 23 additions & 0 deletions src/linux/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/ptrace.h>

#include "../error.h"
#include "../hints.h"
#include "../stats.h"


Expand Down Expand Up @@ -109,3 +111,24 @@ _procfs(pid_t pid, char * file) {

return fp;
}


// ----------------------------------------------------------------------------
static inline char *
proc_root(pid_t pid, char * file) {
if (file[0] != '/') {
log_e("File path is not absolute"); // GCOV_EXCL_START
return NULL; // GCOV_EXCL_STOP
}

char * proc_root = calloc(1, strlen(file) + 24);
if (!isvalid(proc_root))
return NULL; // GCOV_EXCL_LINE

if (sprintf(proc_root, "/proc/%d/root%s", pid, file) < 0) {
free(proc_root); // GCOV_EXCL_START
return NULL; // GCOV_EXCL_STOP
}

return proc_root;
}
26 changes: 13 additions & 13 deletions src/linux/py_proc.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,16 +455,16 @@ _py_proc__parse_maps_file(py_proc_t * self) {
// The first memory map of the executable
if (!isvalid(pd->maps[MAP_BIN].path) && strcmp(pd->exe_path, pathname) == 0) {
map = &(pd->maps[MAP_BIN]);
map->path = strndup(pathname, strlen(pathname));
map->path = proc_root(self->pid, pathname);
if (!isvalid(map->path)) {
log_ie("Cannot duplicate path name");
log_e("Cannot get proc root path for %s", pathname); // GCOV_EXCL_START
set_error(EPROC);
FAIL;
FAIL; // GCOV_EXCL_STOP
}
map->file_size = _file_size(pathname);
map->file_size = _file_size(map->path);
map->base = (void *) lower;
map->size = upper - lower;
map->has_symbols = success(_py_proc__analyze_elf(self, pathname, (void *) lower));
map->has_symbols = success(_py_proc__analyze_elf(self, map->path, (void *) lower));
if (map->has_symbols) {
map->bss_base = self->map.bss.base;
map->bss_size = self->map.bss.size;
Expand All @@ -479,13 +479,13 @@ _py_proc__parse_maps_file(py_proc_t * self) {
int has_symbols = success(_py_proc__analyze_elf(self, pathname, (void *) lower));
if (has_symbols) {
map = &(pd->maps[MAP_LIBSYM]);
map->path = strndup(pathname, strlen(pathname));
map->path = proc_root(self->pid, pathname);
if (!isvalid(map->path)) {
log_ie("Cannot duplicate path name");
log_e("Cannot get proc root path for %s", pathname); // GCOV_EXCL_START
set_error(EPROC);
FAIL;
FAIL; // GCOV_EXCL_STOP
}
map->file_size = _file_size(pathname);
map->file_size = _file_size(map->path);
map->base = (void *) lower;
map->size = upper - lower;
map->has_symbols = TRUE;
Expand All @@ -503,13 +503,13 @@ _py_proc__parse_maps_file(py_proc_t * self) {
unsigned int v;
if (sscanf(needle, "libpython%u.%u", &v, &v) == 2) {
map = &(pd->maps[MAP_LIBNEEDLE]);
map->path = needle_path = strndup(pathname, strlen(pathname));
map->path = needle_path = proc_root(self->pid, pathname);
if (!isvalid(map->path)) {
log_ie("Cannot duplicate path name");
log_e("Cannot get proc root path for %s", pathname); // GCOV_EXCL_START
set_error(EPROC);
FAIL;
FAIL; // GCOV_EXCL_STOP
}
map->file_size = _file_size(pathname);
map->file_size = _file_size(map->path);
map->base = (void *) lower;
map->size = upper - lower;
map->has_symbols = FALSE;
Expand Down
21 changes: 7 additions & 14 deletions src/py_proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,14 @@ _get_version_from_executable(char * binary, int * major, int * minor, int * patc
#endif

fp = _popen(cmd, "r");
if (!isvalid(fp)) {
set_error(EPROC);
if (!isvalid(fp))
FAIL;
}

while (fgets(version, sizeof(version) - 1, fp) != NULL) {
if (sscanf(version, "Python %d.%d.%d", major, minor, patch) == 3)
SUCCESS;
}

set_error(EPROC);
FAIL;
} /* _get_version_from_executable */

Expand All @@ -129,37 +126,34 @@ _get_version_from_filename(char * filename, const char * needle, int * major, in
#if defined PL_LINUX /* LINUX */
char * base = filename;
char * end = base + strlen(base);
size_t needle_len = strlen(needle);

while (base < end) {
base = strstr(base, needle);
if (!isvalid(base)) {
break;
}
if (sscanf(base + strlen(needle), "%u.%u", major, minor) == 2) {
base += needle_len;
if (sscanf(base, "%u.%u", major, minor) == 2) {
SUCCESS;
}
}

#elif defined PL_WIN /* WIN */
// Assume the library path is of the form *.python3[0-9]+[.]dll
int n = strlen(filename);
if (n < 10) {
set_error(EPROC);
if (n < 10)
FAIL;
}

char * p = filename + n - 1;
while (*(p--) != 'n' && p > filename);
p++;
*major = *(p++) - '0';
if (*major != 3) {
set_error(EPROC);
if (*major != 3)
FAIL;
}

if (sscanf(p,"%d.dll", minor) == 1) {
if (sscanf(p,"%d.dll", minor) == 1)
SUCCESS;
}

#elif defined PL_MACOS /* MAC */
char * ver_needle = strstr(filename, "3.");
Expand All @@ -169,7 +163,6 @@ _get_version_from_filename(char * filename, const char * needle, int * major, in

#endif

set_error(EPROC);
FAIL;
} /* _get_version_from_filename */

Expand Down

0 comments on commit 4559915

Please sign in to comment.