aboutsummaryrefslogtreecommitdiff
path: root/proc.c
diff options
context:
space:
mode:
authorPetr Machata <pmachata@redhat.com>2012-10-27 19:23:12 +0200
committerPetr Machata <pmachata@redhat.com>2012-10-27 19:23:12 +0200
commit165b566a50b2bd560af3bd9649e456915397066b (patch)
tree628db7a9bc75ef25d21f596dbea5ffe8bd1cb1bd /proc.c
parent45de1a24740e813ac10b981684a9b46814ddb38c (diff)
downloadltrace-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.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/proc.c b/proc.c
index e601e15..d12faef 100644
--- a/proc.c
+++ b/proc.c
@@ -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;
+}