mirror of
https://github.com/sstefani/mtrace.git
synced 2025-12-06 16:56:41 +08:00
better cwd handling of traced process
This commit is contained in:
parent
033747ca32
commit
60ee5fe123
18
backend.h
18
backend.h
@ -34,16 +34,19 @@
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Convert a PID to a path to the corresponding binary. */
|
||||
/* Convert a pid to a path to the corresponding binary. */
|
||||
char *pid2name(pid_t pid);
|
||||
|
||||
/* Given a PID, find a leader of thread group. */
|
||||
/* return the cwd of a pid. */
|
||||
char *pid2cwd(pid_t pid);
|
||||
|
||||
/* Given a pid, find a leader of thread group. */
|
||||
pid_t process_leader(pid_t pid);
|
||||
|
||||
/* Given a PID of leader thread, fill in PIDs of all the tasks. The
|
||||
* function will initialize the pointer *RET_TASKS to a
|
||||
/* Given a pid of leader thread, fill in pids of all the tasks. The
|
||||
* function will initialize the pointer *ret_tasks to a
|
||||
* newly-allocated array, and will store number of elements in that
|
||||
* array to *RET_N. You have to free that buffer when you don't need
|
||||
* array to *ret_n. You have to free that buffer when you don't need
|
||||
* it anymore. */
|
||||
int process_tasks(pid_t pid, pid_t **ret_tasks, size_t *ret_n);
|
||||
|
||||
@ -56,8 +59,7 @@ void trace_me(void);
|
||||
/* stop tracing a task. */
|
||||
int untrace_task(struct task *task, int signum);
|
||||
|
||||
/* Called when mtrace needs to attach to task, such as when it attaches
|
||||
* to a running process, whose PID is given on the command line. */
|
||||
/* Called when mtrace needs to attach to task */
|
||||
int trace_attach(struct task *task);
|
||||
|
||||
/* wait for a task ready for tracing */
|
||||
@ -127,7 +129,7 @@ int linkmap_init(struct task *task, arch_addr_t dyn_addr);
|
||||
|
||||
/* This should extract entry point address and interpreter (dynamic
|
||||
* linker) bias if possible. Returns 0 if there were no errors, -1
|
||||
* otherwise. Sets *ENTRYP and *INTERP_BIASP to non-zero values if
|
||||
* otherwise. Sets *entryp and *interp_biasp to non-zero values if
|
||||
* the corresponding value is known, or zero otherwise; this is not
|
||||
* done for pointers that are NULL. */
|
||||
int process_get_entry(struct task *task, unsigned long *entryp, unsigned long *interp_biasp);
|
||||
|
||||
40
mtelf.c
40
mtelf.c
@ -48,14 +48,32 @@
|
||||
#include "common.h"
|
||||
#include "report.h"
|
||||
|
||||
static int open_elf(struct mt_elf *mte, const char *filename)
|
||||
static int open_elf(struct mt_elf *mte, struct task *task, const char *filename)
|
||||
{
|
||||
mte->filename = filename;
|
||||
char *cwd;
|
||||
|
||||
if (options.cwd != -1)
|
||||
mte->fd = openat(options.cwd, filename, O_RDONLY);
|
||||
else
|
||||
mte->fd = open(filename, O_RDONLY);
|
||||
mte->filename = filename;
|
||||
mte->fd = -1;
|
||||
|
||||
cwd = pid2cwd(task->pid);
|
||||
if (cwd) {
|
||||
int fd = open(cwd, O_RDONLY|O_DIRECTORY);
|
||||
|
||||
if (fd != -1) {
|
||||
mte->fd = openat(fd, filename, O_RDONLY);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
free(cwd);
|
||||
}
|
||||
|
||||
if (mte->fd == -1) {
|
||||
if (options.cwd != -1)
|
||||
mte->fd = openat(options.cwd, filename, O_RDONLY);
|
||||
else
|
||||
mte->fd = open(filename, O_RDONLY);
|
||||
}
|
||||
|
||||
if (mte->fd == -1)
|
||||
return 1;
|
||||
@ -236,11 +254,11 @@ static void close_elf(struct mt_elf *mte)
|
||||
}
|
||||
}
|
||||
|
||||
static int elf_read(struct mt_elf *mte, const char *filename, GElf_Addr bias)
|
||||
static int elf_read(struct mt_elf *mte, struct task *task, const char *filename, GElf_Addr bias)
|
||||
{
|
||||
debug(DEBUG_FUNCTION, "filename=%s", filename);
|
||||
|
||||
if (open_elf(mte, filename) < 0)
|
||||
if (open_elf(mte, task, filename) < 0)
|
||||
return -1;
|
||||
|
||||
GElf_Phdr phdr;
|
||||
@ -351,7 +369,7 @@ int elf_read_library(struct task *task, struct library *lib, const char *filenam
|
||||
|
||||
library_set_filename(lib, filename);
|
||||
|
||||
if (elf_read(&mte, filename, bias) == -1)
|
||||
if (elf_read(&mte, task, filename, bias) == -1)
|
||||
return -1;
|
||||
|
||||
mte.bias = bias;
|
||||
@ -456,7 +474,7 @@ struct library *elf_read_main_binary(struct task *task)
|
||||
|
||||
library_set_filename(lib, strdup(fname));
|
||||
|
||||
if (elf_read(&mte, filename, 0) == -1)
|
||||
if (elf_read(&mte, task, filename, 0) == -1)
|
||||
goto fail3;
|
||||
|
||||
task->is_64bit = is_64bit(&mte);
|
||||
@ -490,7 +508,7 @@ struct library *elf_read_main_binary(struct task *task)
|
||||
|
||||
copy_str_from_proc(task, ARCH_ADDR_T(mte.interp), fname, sizeof(fname));
|
||||
|
||||
if (!elf_read(&mte_ld, fname, (GElf_Addr)base)) {
|
||||
if (!elf_read(&mte_ld, task, fname, (GElf_Addr)base)) {
|
||||
mte_ld.bias = (GElf_Addr)base;
|
||||
mte_ld.entry_addr = mte_ld.ehdr.e_entry + (GElf_Addr)base;
|
||||
|
||||
|
||||
@ -71,6 +71,24 @@ char *pid2name(pid_t pid)
|
||||
return strdup(proc_exe);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a (malloc'd) file name corresponding to a running pid
|
||||
*/
|
||||
char *pid2cwd(pid_t pid)
|
||||
{
|
||||
int ret;
|
||||
char fname[PATH_MAX];
|
||||
PROC_PID_FILE(proc_cwd, "/proc/%d/cwd", pid);
|
||||
|
||||
ret = readlink(proc_cwd, fname, sizeof(fname) - 1);
|
||||
if (ret == -1)
|
||||
return NULL;
|
||||
|
||||
fname[ret] = 0;
|
||||
|
||||
return strdup(fname);
|
||||
}
|
||||
|
||||
static FILE *open_status_file(pid_t pid)
|
||||
{
|
||||
PROC_PID_FILE(fn, "/proc/%d/status", pid);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user