diff options
author | Mikhail Durnev <mikhail_durnev@mentor.com> | 2020-07-10 08:58:35 +1000 |
---|---|---|
committer | Dave Watson <dade.watson@gmail.com> | 2020-07-15 08:02:54 -0700 |
commit | 831459ee961e7d673bbd83e40d0823227c66db33 (patch) | |
tree | c8ed1b27cf61032eab3eeb5f525d475efbfe8bd6 /src | |
parent | 1a5ebbd0b9befb0cfd856a1de2a9d43937c2d7a3 (diff) | |
download | libunwind-831459ee961e7d673bbd83e40d0823227c66db33.tar.gz |
linux: Use /proc/[pid]/root
When we are backtracing processes running in a container, we cannot rely on ELF paths
in /proc/[pid]/maps. Those paths are valid inside the container. We have to add
/proc/[pid]/root to each path to access the ELF files from outside of the container.
Signed-off-by: Mikhail Durnev <mikhail_durnev@mentor.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/os-linux.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/src/os-linux.c b/src/os-linux.c index 8a00669f..d233fd40 100644 --- a/src/os-linux.c +++ b/src/os-linux.c @@ -25,6 +25,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include <limits.h> #include <stdio.h> +#include <sys/stat.h> #include "libunwind_i.h" #include "os-linux.h" @@ -37,6 +38,10 @@ tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, struct map_iterator mi; int found = 0, rc; unsigned long hi; + char root[sizeof ("/proc/0123456789/root")], *cp; + char *full_path; + struct stat st; + if (maps_init (&mi, pid) < 0) return -1; @@ -53,11 +58,36 @@ tdep_get_elf_image (struct elf_image *ei, pid_t pid, unw_word_t ip, maps_close (&mi); return -1; } + + full_path = mi.path; + + /* Get process root */ + memcpy (root, "/proc/", 6); + cp = unw_ltoa (root + 6, pid); + assert (cp + 6 < root + sizeof (root)); + memcpy (cp, "/root", 6); + + if (!stat(root, &st) && S_ISDIR(st.st_mode)) + { + full_path = (char*) malloc (strlen (root) + strlen (mi.path) + 1); + if (!full_path) + full_path = mi.path; + else + { + strcpy (full_path, root); + strcat (full_path, mi.path); + } + } + if (path) { - strncpy(path, mi.path, pathlen); + strncpy(path, full_path, pathlen); } - rc = elf_map_image (ei, mi.path); + rc = elf_map_image (ei, full_path); + + if (full_path && full_path != mi.path) + free (full_path); + maps_close (&mi); return rc; } |