[PATCH] printcall(): lookup eip address through /proc/<pid>/maps
Yann Droneaud
yann at droneaud.fr
Tue Dec 1 16:57:35 UTC 2009
POC: Try to report which object is calling a syscall
This could be useful to diagnose which library is doing the syscall.
Sadly, it's not very useful: under Linux, syscall are done by glibc
through a syscall() wrapper which in turn use a virtual library
linux-gate.so.1 (also known as vdso) so every syscall is reported from
this particular object.
Not very useful.
---
util.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 65 insertions(+), 0 deletions(-)
diff --git a/util.c b/util.c
index 78b1427..01acbb4 100644
--- a/util.c
+++ b/util.c
@@ -1212,6 +1212,70 @@ getpc(struct tcb *tcp)
}
#endif /* 0 */
+/* let slow things a bit
+ *
+ * content of /proc/<pid>/maps should be kept in cache
+ * and updated only on
+ * - mmap()
+ * - munmap()
+ * - brk()
+ * - exec*()
+ * - ...
+ */
+void
+printobject(struct tcb *tcp, long eip)
+{
+ char buffer[256];
+ FILE *f;
+
+ sprintf(buffer, "/proc/%d/maps", tcp->pid);
+
+ f = fopen(buffer, "r");
+ if (f == NULL) {
+ return;
+ }
+
+ while(1) {
+
+ int ret;
+
+ long begin;
+ long end;
+
+ char rights[256];
+ long arg0, arg1, arg2, arg3;
+
+ char object[256];
+
+ if (fgets(buffer, 256, f) == NULL) {
+ break;
+ }
+
+ object[0] = '\0';
+ begin = 0;
+ end = 0;
+
+ ret = sscanf(buffer, "%lx-%lx %s %lx %lx:%lx %ld %s", &begin, &end, rights, &arg0, &arg1, &arg2, &arg3, object);
+
+ if (ret < 2) {
+ continue;
+ }
+
+ if (eip >= begin && eip < end) {
+ if (ret == 8 && object[0] != '\0') {
+ tprintf("%s:", object);
+ } else {
+ tprintf("unknown:");
+ }
+
+ break;
+ }
+
+ }
+
+ fclose(f);
+}
+
void
printcall(struct tcb *tcp)
{
@@ -1227,6 +1291,7 @@ printcall(struct tcb *tcp)
PRINTBADPC;
return;
}
+ printobject(tcp, eip);
tprintf("[%08lx] ", eip);
# elif defined(S390) || defined(S390X)
--
1.6.0.2
More information about the Strace-devel
mailing list