summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMikhail Durnev <mikhail_durnev@mentor.com>2020-07-10 08:58:35 +1000
committerDave Watson <dade.watson@gmail.com>2020-07-15 08:02:54 -0700
commit831459ee961e7d673bbd83e40d0823227c66db33 (patch)
treec8ed1b27cf61032eab3eeb5f525d475efbfe8bd6 /src
parent1a5ebbd0b9befb0cfd856a1de2a9d43937c2d7a3 (diff)
downloadlibunwind-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.c34
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;
}