diff options
author | Petr Machata <pmachata@redhat.com> | 2012-10-27 19:23:12 +0200 |
---|---|---|
committer | Petr Machata <pmachata@redhat.com> | 2012-10-27 19:23:12 +0200 |
commit | 165b566a50b2bd560af3bd9649e456915397066b (patch) | |
tree | 628db7a9bc75ef25d21f596dbea5ffe8bd1cb1bd /proc.c | |
parent | 45de1a24740e813ac10b981684a9b46814ddb38c (diff) | |
download | ltrace-165b566a50b2bd560af3bd9649e456915397066b.tar.gz |
Add proc_find_symbol, use it to find corresponding symbols for clones
The code in breakpoint_clone was buggy--it looked through old_proc's
symbols. It was also needlessly verbose, proc_find_symbol uses library
key to find the right library. Instead use the new interface and call
it on new_proc to find the new symbol.
We also didn't relink symbols in stack elements of a cloned process in
process_clone. Use proc_find_symbol for this as well.
Diffstat (limited to 'proc.c')
-rw-r--r-- | proc.c | 36 |
1 files changed, 36 insertions, 0 deletions
@@ -420,6 +420,16 @@ process_clone(struct Process *retp, struct Process *proc, pid_t pid) } retp->callstack[i].arguments = nargs; } + + /* If it's not a syscall, we need to find the + * corresponding library symbol in the cloned + * library. */ + if (!elem->is_syscall && elem->c_un.libfunc != NULL) { + struct library_symbol *libfunc = elem->c_un.libfunc; + int rc = proc_find_symbol(retp, libfunc, + NULL, &elem->c_un.libfunc); + assert(rc == 0); + } } if (os_process_clone(retp, proc) < 0 @@ -949,3 +959,29 @@ proc_each_breakpoint(struct Process *proc, void *start, dict_apply_to_all(proc->breakpoints, &each_breakpoint_cb, &dd); return dd.end; } + +int +proc_find_symbol(struct Process *proc, struct library_symbol *sym, + struct library **retlib, struct library_symbol **retsym) +{ + struct library *lib = sym->lib; + assert(lib != NULL); + + struct library *flib + = proc_each_library(proc, NULL, library_with_key_cb, &lib->key); + if (flib == NULL) + return -1; + + struct library_symbol *fsym + = library_each_symbol(flib, NULL, library_symbol_named_cb, + (char *)sym->name); + if (fsym == NULL) + return -1; + + if (retlib != NULL) + *retlib = flib; + if (retsym != NULL) + *retsym = fsym; + + return 0; +} |