This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: baby memory map notification
- From: Srinivasa DS <srinivasa at in dot ibm dot com>
- To: David Smith <dsmith at redhat dot com>
- Cc: "Frank Ch. Eigler" <fche at redhat dot com>, Systemtap List <systemtap at sources dot redhat dot com>
- Date: Tue, 24 Jun 2008 17:07:47 +0530
- Subject: Re: baby memory map notification
- References: <48502358.4070404@redhat.com> <48601AE0.30908@redhat.com>
David Smith wrote:
David Smith wrote:
Frank,
Here's a stab at baby memory map notification. It works, with several
limitations:
I've checked in a new-and-improved version. This one:
- works on existing threads and new threads (tracking new vms as they
get created and deleted)
- you can use .begin probes (you couldn't do that with the last version)
- even works on 32-bit x86 apps running on 64-bit x86_64 kernel
Limitations:
- because of a utrace bug, it won't work on fedora x86 2.6.25 kernels
(it works fine on fedora x86_64 2.6.25 kernels)
- paths for deleted vma's are currently passed to the callback as NULL
- I haven't tested this against a multi-threaded app yet
- almost all testing has been done on x86_64/f9, so that is where it
will work best
Everything you need should be checked in, but disabled by default. To
enable, define 'DEBUG_TASK_FINDER_VMA'. With the attached script, you
can run:
# stap -v -DDEBUG_TASK_FINDER_VMA cat.stp
I tried executing this script on ppc64 system, But later found that
memory map notification was not implemented on ppc64. So I did few
changes to make it work for ppc64. Iam attaching my patch here, please
let me know your comments.
Snapshot of script output
=================
stapio:stp_main_loop:318 nb=12
stapio:stp_main_loop:358 probe_start() returned 0
running...
__stp_tf_vm_cb:47: vm_cb: tsk 30717:1 path /lib/ld-2.5.so, start
0x0ffc0000, end 0x0ffe0000, offset 0x0
__stp_tf_vm_cb:47: vm_cb: tsk 30717:1 path /lib/ld-2.5.so, start
0x0ffe0000, end 0x10000000, offset 0x10000
__stp_tf_vm_cb:47: vm_cb: tsk 30717:1 path /bin/cat, start 0x10000000,
end 0x10010000, offset 0x0
__stp_tf_vm_cb:47: vm_cb: tsk 30717:1 path /bin/cat, start 0x10010000,
end 0x10020000, offset 0x0
*** /bin/cat begin ***
__stp_utrace_task_finder_target_syscall_exit:772: tsk 30717 found
mmap(0xf7fc0000), returned 0xf7fc0000
__stp_tf_vm_cb:47: vm_cb: tsk 30717:1 path /etc/ld.so.cache, start
0xf7fc0000, end 0xf7ff0000, offset 0x0
__stp_utrace_task_finder_target_syscall_exit:772: tsk 30717 found
mmap(0xfe30000), returned 0xfe30000
__stp_tf_vm_cb:47: vm_cb: tsk 30717:1 path /lib/libc-2.5.so, start
0x0fe30000, end 0x0ffc0000, offset 0x0
__stp_utrace_task_finder_target_syscall_exit:772: tsk 30717 found
mmap(0xffa0000), returned 0xffa0000
=======================
Signed-off-by: Srinivasa DS <srinivasa@in.ibm.com>
---
runtime/syscall.h | 39 ++++++++++++++++++++++++++++++++++++---
1 file changed, 36 insertions(+), 3 deletions(-)
Index: systemtap/runtime/syscall.h
===================================================================
--- systemtap.orig/runtime/syscall.h
+++ systemtap/runtime/syscall.h
@@ -49,15 +49,29 @@
# endif
#endif
+#if defined(__powerpc__)
+#define __MMAP_SYSCALL_NO_PPC64 90
+#define __MPROTECT_SYSCALL_NO_PPC64 125
+#define __MUNMAP_SYSCALL_NO_PPC64 91
+#define __MREMAP_SYSCALL_NO_PPC64 163
+#define MMAP_SYSCALL_NO(tsk) __MMAP_SYSCALL_NO_PPC64
+#define MPROTECT_SYSCALL_NO(tsk) __MPROTECT_SYSCALL_NO_PPC64
+#define MUNMAP_SYSCALL_NO(tsk) __MUNMAP_SYSCALL_NO_PPC64
+#define MREMAP_SYSCALL_NO(tsk) __MREMAP_SYSCALL_NO_PPC64
+#endif
+
#if !defined(MMAP_SYSCALL_NO) || !defined(MPROTECT_SYSCALL_NO) \
|| !defined(MUNMAP_SYSCALL_NO) || !defined(MREMAP_SYSCALL_NO)
#error "Unimplemented architecture"
#endif
-#if defined(__i386__) || defined(__x86_64__)
+#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__)
static inline unsigned long
__stp_user_syscall_nr(struct pt_regs *regs)
{
+#if defined(__powerpc__)
+ return regs->gpr[0];
+#else
#if defined(STAPCONF_X86_UNIREGS)
return regs->orig_ax;
#elif defined(__x86_64__)
@@ -65,13 +79,17 @@ __stp_user_syscall_nr(struct pt_regs *re
#elif defined (__i386__)
return regs->orig_eax;
#endif
+#endif
}
#endif
-#if defined(__i386__) || defined(__x86_64__)
+#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__)
static inline long *
__stp_user_syscall_return_value(struct task_struct *task, struct
pt_regs *regs)
{
+#if defined(__powerpc__)
+ return ®s->gpr[3];
+#else
#ifdef CONFIG_IA32_EMULATION
// This code works, but isn't what we need. Since
// __stp_user_syscall_arg() doesn't sign-extend, a value passed in as
@@ -91,14 +109,28 @@ __stp_user_syscall_return_value(struct t
#elif defined (__i386__)
return ®s->eax;
#endif
+#endif
}
#endif
-#if defined(__i386__) || defined(__x86_64__)
+#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__)
static inline long *
__stp_user_syscall_arg(struct task_struct *task, struct pt_regs *regs,
unsigned int n)
{
+#if defined(__powerpc__)
+ switch (n) {
+ case 0: return ®s->gpr[3];
+ case 1: return ®s->gpr[4];
+ case 2: return ®s->gpr[5];
+ case 3: return ®s->gpr[6];
+ case 4: return ®s->gpr[7];
+ case 5: return ®s->gpr[8];
+ default:
+ _stp_error("syscall arg > 5");
+ return NULL;
+ }
+#else
#if defined(__i386__)
if (n > 5) {
_stp_error("syscall arg > 5");
@@ -154,6 +186,7 @@ __stp_user_syscall_arg(struct task_struc
return NULL;
}
#endif /* CONFIG_X86_32 */
+#endif
}
#endif