Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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