Merge branch 'for-pierre-marc' of git://git.infradead.org/users/jblunck/ust
authorPierre-Marc Fournier <pierre-marc.fournier@polymtl.ca>
Tue, 27 Oct 2009 22:58:15 +0000 (18:58 -0400)
committerPierre-Marc Fournier <pierre-marc.fournier@polymtl.ca>
Tue, 27 Oct 2009 22:58:15 +0000 (18:58 -0400)
Fixed conflicts:
include/ust/marker.h

include/ust/marker.h
libust/marker.c
libust/processor.h [new file with mode: 0644]
libust/serialize.c
libust/tracectl.c
libust/tracer.h
ustd/ustd.c
usttrace

index 2b5a0c38ba701dfe6f1874eecee097b6bbd47e5a..5c7d1b362b7b3f22dd153d1bdefab7ac3c09ee46 100644 (file)
@@ -30,6 +30,7 @@
 //ust// #include <linux/ltt-channels.h>
 #include <ust/kernelcompat.h>
 #include <kcompat/list.h>
+#include "processor.h"
 
 //ust// struct module;
 //ust// struct task_struct;
@@ -49,7 +50,7 @@ struct marker;
  * format string to recover the variable argument list.
  */
 typedef void marker_probe_func(const struct marker *mdata,
-               void *probe_private, void *call_private,
+               void *probe_private, struct registers *regs, void *call_private,
                const char *fmt, va_list *args);
 
 struct marker_probe_closure {
@@ -68,11 +69,12 @@ struct marker {
                                /* Probe wrapper */
        u16 channel_id;         /* Numeric channel identifier, dynamic */
        u16 event_id;           /* Numeric event identifier, dynamic */
-       void (*call)(const struct marker *mdata, void *call_private, ...);
+       void (*call)(const struct marker *mdata, void *call_private, struct registers *regs, ...);
        struct marker_probe_closure single;
        struct marker_probe_closure *multi;
        const char *tp_name;    /* Optional tracepoint name */
        void *tp_cb;            /* Optional tracepoint callback */
+       void *location;         /* Address of marker in code */
 } __attribute__((aligned(8)));
 
 #define CONFIG_MARKERS
@@ -82,6 +84,7 @@ struct marker {
                static const char __mstrtab_##channel##_##name[]        \
                __attribute__((section("__markers_strings")))           \
                = #channel "\0" #name "\0" format;                      \
+               struct registers regs;                                  \
                static struct marker __mark_##channel##_##name          \
                __attribute__((section("__markers"), aligned(8))) =     \
                { __mstrtab_##channel##_##name,                         \
@@ -90,7 +93,15 @@ struct marker {
                                                sizeof(#name)],         \
                  0, 0, 0, 0, marker_probe_cb,                          \
                  { __mark_empty_function, NULL},                       \
-                 NULL, tp_name_str, tp_cb }
+                 NULL, tp_name_str, tp_cb, NULL };                     \
+               asm (".section __marker_addr,\"aw\",@progbits\n\t"      \
+                      _ASM_PTR "%c[marker_struct], (1f)\n\t"           \
+                      ".previous\n\t"                                  \
+                      "1:\n\t"                                         \
+                       :: [marker_struct] "i" (&__mark_##channel##_##name));\
+               save_registers(&regs)
+
+
 
 #define DEFINE_MARKER(channel, name, format)                           \
                _DEFINE_MARKER(channel, name, NULL, NULL, format)
@@ -116,13 +127,13 @@ struct marker {
                                        __mark_##channel##_##name.state))) \
                                (*__mark_##channel##_##name.call)       \
                                        (&__mark_##channel##_##name,    \
-                                       call_private, ## args);         \
+                                       call_private, &regs, ## args);          \
                } else {                                                \
                        if (unlikely(_imv_read(                         \
                                        __mark_##channel##_##name.state))) \
                                (*__mark_##channel##_##name.call)       \
                                        (&__mark_##channel##_##name,    \
-                                       call_private, ## args);         \
+                                       call_private, &regs, ## args);          \
                }                                                       \
        } while (0)
 
@@ -136,7 +147,7 @@ struct marker {
                DEFINE_MARKER_TP(channel, name, tp_name, tp_cb, format);\
                __mark_check_format(format, ## args);                   \
                (*__mark_##channel##_##name.call)(&__mark_##channel##_##name, \
-                       call_private, ## args);                         \
+                       call_private, &regs, ## args);                          \
        } while (0)
 
 extern void marker_update_probe_range(struct marker *begin,
@@ -230,7 +241,7 @@ static inline void __printf(1, 2) ___mark_check_format(const char *fmt, ...)
 extern marker_probe_func __mark_empty_function;
 
 extern void marker_probe_cb(const struct marker *mdata,
-       void *call_private, ...);
+       void *call_private, struct registers *regs, ...);
 
 /*
  * Connect a probe to a marker.
@@ -286,23 +297,29 @@ extern int is_marker_enabled(const char *channel, const char *name);
 //ust// }
 //ust// #endif
 
+struct marker_addr {
+       struct marker *marker;
+       void *addr;
+};
 
 struct lib {
        struct marker *markers_start;
+       struct marker_addr *markers_addr_start;
        int markers_count;
        struct list_head list;
 };
 
-extern int marker_register_lib(struct marker *markers_start,
-                              int markers_count);
-
-#define MARKER_LIB                                                     \
-extern struct marker __start___markers[] __attribute__((visibility("hidden")));        \
-extern struct marker __stop___markers[] __attribute__((visibility("hidden")));         \
-                                                                                       \
-static void __attribute__((constructor)) __markers__init(void)                                 \
-{                                                                                      \
-       marker_register_lib(__start___markers, (((long)__stop___markers)-((long)__start___markers))/sizeof(struct marker));\
+extern int marker_register_lib(struct marker *markers_start, struct marker_addr *marker_addr_start, int markers_count);
+
+#define MARKER_LIB                                                                             \
+extern struct marker __start___markers[] __attribute__((visibility("hidden")));                        \
+extern struct marker __stop___markers[] __attribute__((visibility("hidden")));                 \
+extern struct marker_addr __start___marker_addr[] __attribute__((visibility("hidden")));       \
+extern struct marker_addr __stop___marker_addr[] __attribute__((visibility("hidden")));                \
+                                                                                               \
+static void __attribute__((constructor)) __markers__init(void)                                 \
+{                                                                                              \
+       marker_register_lib(__start___markers, __start___marker_addr, (((long)__stop___markers)-((long)__start___markers))/sizeof(struct marker)); \
 }
 
 extern void marker_set_new_marker_cb(void (*cb)(struct marker *));
index 8690d2b1151e0a5861c2c81327226cb55e46757a..b543b166bcd52bd26928da736f69481e9b73c03d 100644 (file)
@@ -43,6 +43,8 @@
 
 extern struct marker __start___markers[] __attribute__((visibility("hidden")));
 extern struct marker __stop___markers[] __attribute__((visibility("hidden")));
+extern struct marker_addr __start___marker_addr[] __attribute__((visibility("hidden")));
+extern struct marker_addr __stop___marker_addr[] __attribute__((visibility("hidden")));
 
 /* Set to 1 to enable marker debug output */
 static const int marker_debug;
@@ -87,7 +89,7 @@ struct marker_entry {
        char *format;
        char *name;
                        /* Probe wrapper */
-       void (*call)(const struct marker *mdata, void *call_private, ...);
+       void (*call)(const struct marker *mdata, void *call_private, struct registers *regs, ...);
        struct marker_probe_closure single;
        struct marker_probe_closure *multi;
        int refcount;   /* Number of times armed. 0 if disarmed. */
@@ -123,7 +125,7 @@ static void marker_update_processes(void)
  * operations that modifies the execution flow of preemptible code.
  */
 notrace void __mark_empty_function(const struct marker *mdata,
-       void *probe_private, void *call_private, const char *fmt, va_list *args)
+       void *probe_private, struct registers *regs, void *call_private, const char *fmt, va_list *args)
 {
 }
 //ust// EXPORT_SYMBOL_GPL(__mark_empty_function);
@@ -139,7 +141,7 @@ notrace void __mark_empty_function(const struct marker *mdata,
  * rcu_dereference() for the pointer read.
  */
 notrace void marker_probe_cb(const struct marker *mdata,
-               void *call_private, ...)
+               void *call_private, struct registers *regs, ...)
 {
        va_list args;
        char ptype;
@@ -160,8 +162,8 @@ notrace void marker_probe_cb(const struct marker *mdata,
                /* Must read the ptr before private data. They are not data
                 * dependant, so we put an explicit smp_rmb() here. */
                smp_rmb();
-               va_start(args, call_private);
-               func(mdata, mdata->single.probe_private, call_private,
+               va_start(args, regs);
+               func(mdata, mdata->single.probe_private, regs, call_private,
                        mdata->format, &args);
                va_end(args);
        } else {
@@ -181,9 +183,9 @@ notrace void marker_probe_cb(const struct marker *mdata,
                 */
                smp_read_barrier_depends();
                for (i = 0; multi[i].func; i++) {
-                       va_start(args, call_private);
+                       va_start(args, regs);
                        multi[i].func(mdata, multi[i].probe_private,
-                               call_private, mdata->format, &args);
+                               regs, call_private, mdata->format, &args);
                        va_end(args);
                }
        }
@@ -200,7 +202,7 @@ notrace void marker_probe_cb(const struct marker *mdata,
  * Should be connected to markers "MARK_NOARGS".
  */
 static notrace void marker_probe_cb_noarg(const struct marker *mdata,
-               void *call_private, ...)
+               void *call_private, struct registers *regs, ...)
 {
        va_list args;   /* not initialized */
        char ptype;
@@ -216,7 +218,7 @@ static notrace void marker_probe_cb_noarg(const struct marker *mdata,
                /* Must read the ptr before private data. They are not data
                 * dependant, so we put an explicit smp_rmb() here. */
                smp_rmb();
-               func(mdata, mdata->single.probe_private, call_private,
+               func(mdata, mdata->single.probe_private, regs, call_private,
                        mdata->format, &args);
        } else {
                struct marker_probe_closure *multi;
@@ -235,7 +237,7 @@ static notrace void marker_probe_cb_noarg(const struct marker *mdata,
                 */
                smp_read_barrier_depends();
                for (i = 0; multi[i].func; i++)
-                       multi[i].func(mdata, multi[i].probe_private,
+                       multi[i].func(mdata, multi[i].probe_private, regs,
                                call_private, mdata->format, &args);
        }
 //ust//        rcu_read_unlock_sched_notrace();
@@ -823,6 +825,7 @@ int marker_probe_register(const char *channel, const char *name,
        }
        mutex_unlock(&markers_mutex);
 
+       /* Activate marker if necessary */
        marker_update_probes();
 
        mutex_lock(&markers_mutex);
@@ -1495,15 +1498,22 @@ static void new_markers(struct marker *start, struct marker *end)
        }
 }
 
-int marker_register_lib(struct marker *markers_start, int markers_count)
+int marker_register_lib(struct marker *markers_start, struct marker_addr *marker_addr_start, int markers_count)
 {
        struct lib *pl;
+       struct marker_addr *addr;
 
        pl = (struct lib *) malloc(sizeof(struct lib));
 
        pl->markers_start = markers_start;
+       pl->markers_addr_start = marker_addr_start;
        pl->markers_count = markers_count;
 
+       lock_markers();
+       for(addr = marker_addr_start; addr < marker_addr_start + markers_count; addr++)
+               addr->marker->location = addr->addr;
+       unlock_markers();
+
        /* FIXME: maybe protect this with its own mutex? */
        lock_markers();
        list_add(&pl->list, &libs);
@@ -1532,8 +1542,8 @@ static int initialized = 0;
 void __attribute__((constructor)) init_markers(void)
 {
        if(!initialized) {
-               marker_register_lib(__start___markers, (((long)__stop___markers)-((long)__start___markers))/sizeof(struct marker));
-               DBG("markers_start: %p, markers_stop: %p\n", __start___markers, __stop___markers);
+               marker_register_lib(__start___markers, __start___marker_addr, (((long)__stop___markers)-((long)__start___markers))/sizeof(struct marker));
+               //DBG("markers_start: %p, markers_stop: %p\n", __start___markers, __stop___markers);
                initialized = 1;
        }
 }
diff --git a/libust/processor.h b/libust/processor.h
new file mode 100644 (file)
index 0000000..1eb5843
--- /dev/null
@@ -0,0 +1,107 @@
+#ifndef UST_PROCESSOR_H
+#define UST_PROCESSOR_H
+
+#include <stddef.h>
+
+#ifdef X86_32
+
+struct registers {
+       long eax;
+       long ebx;
+       long ecx;
+       long edx;
+       long ebp;
+       long esp;
+       long esi;
+       long edi;
+       int  xds;
+       int  xes;
+       int  xfs;
+       int  xgs;
+       long eip;
+       int  xcs;
+       long eflags;
+       int  xss;
+};
+
+static inline save_registers(struct registers *regs)
+{
+}
+
+#define RELATIVE_ADDRESS(__rel_label__) __rel_label__
+
+#define _ASM_PTR ".long "
+
+#else
+
+struct registers {
+       unsigned long rax;
+       unsigned long rbx;
+       unsigned long rcx;
+       unsigned long rdx;
+       unsigned long rbp;
+       unsigned long rsp;
+       unsigned long rsi;
+       unsigned long rdi;
+       unsigned long r8;
+       unsigned long r9;
+       unsigned long r10;
+       unsigned long r11;
+       unsigned long r12;
+       unsigned long r13;
+       unsigned long r14;
+       unsigned long r15;
+       int cs;
+       int ss;
+};
+
+#define save_registers(regsptr) \
+       asm ("movq %%rax,%c[rax_off](%[regs])\n\t" \
+            "movq %%rbx,%c[rbx_off](%[regs])\n\t" \
+            "movq %%rcx,%c[rcx_off](%[regs])\n\t" \
+            "movq %%rdx,%c[rdx_off](%[regs])\n\t" \
+            "movq %%rbp,%c[rbp_off](%[regs])\n\t" \
+            "movq %%rsp,%c[rsp_off](%[regs])\n\t" \
+            "movq %%rsi,%c[rsi_off](%[regs])\n\t" \
+            "movq %%rdi,%c[rdi_off](%[regs])\n\t" \
+            "movq %%r8,%c[r8_off](%[regs])\n\t" \
+            "movq %%r9,%c[r9_off](%[regs])\n\t" \
+            "movq %%r10,%c[r10_off](%[regs])\n\t" \
+            "movq %%r11,%c[r11_off](%[regs])\n\t" \
+            "movq %%r12,%c[r12_off](%[regs])\n\t" \
+            "movq %%r13,%c[r13_off](%[regs])\n\t" \
+            "movq %%r14,%c[r14_off](%[regs])\n\t" \
+            "movq %%r15,%c[r15_off](%[regs])\n\t" \
+            "movw %%cs,%c[cs_off](%[regs])\n\t" \
+            "movw %%ss,%c[ss_off](%[regs])\n\t" \
+       : \
+       : [regs] "r" (regsptr), \
+         [rax_off] "i" (offsetof(struct registers, rax)), \
+         [rbx_off] "i" (offsetof(struct registers, rbx)), \
+         [rcx_off] "i" (offsetof(struct registers, rcx)), \
+         [rdx_off] "i" (offsetof(struct registers, rdx)), \
+         [rbp_off] "i" (offsetof(struct registers, rbp)), \
+         [rsp_off] "i" (offsetof(struct registers, rsp)), \
+         [rsi_off] "i" (offsetof(struct registers, rsi)), \
+         [rdi_off] "i" (offsetof(struct registers, rdi)), \
+         [r8_off] "i" (offsetof(struct registers, r8)), \
+         [r9_off] "i" (offsetof(struct registers, r9)), \
+         [r10_off] "i" (offsetof(struct registers, r10)), \
+         [r11_off] "i" (offsetof(struct registers, r11)), \
+         [r12_off] "i" (offsetof(struct registers, r12)), \
+         [r13_off] "i" (offsetof(struct registers, r13)), \
+         [r14_off] "i" (offsetof(struct registers, r14)), \
+         [r15_off] "i" (offsetof(struct registers, r15)), \
+         [cs_off] "i" (offsetof(struct registers, cs)), \
+         [ss_off] "i" (offsetof(struct registers, ss)) \
+       );
+
+/* Macro to insert the address of a relative jump in an assembly stub,
+ * in a relocatable way. On x86-64, this uses a special (%rip) notation. */
+#define RELATIVE_ADDRESS(__rel_label__) __rel_label__(%%rip)
+
+#define _ASM_PTR ".quad "
+
+#endif
+
+#endif /* UST_PROCESSOR_H */
index 99d4dce4194e076ea5644d9780a89f14ff33a480..beaf6390b544a4dd96f0b4c30afdb0692283435f 100644 (file)
@@ -583,7 +583,8 @@ void ltt_write_event_data(struct rchan_buf *buf, size_t buf_offset,
 
 
 notrace void ltt_vtrace(const struct marker *mdata, void *probe_data,
-                       void *call_data, const char *fmt, va_list *args)
+                       struct registers *regs, void *call_data,
+                       const char *fmt, va_list *args)
 {
        int largest_align, ret;
        struct ltt_active_marker *pdata;
@@ -697,12 +698,13 @@ notrace void ltt_vtrace(const struct marker *mdata, void *probe_data,
 }
 
 notrace void ltt_trace(const struct marker *mdata, void *probe_data,
-                      void *call_data, const char *fmt, ...)
+                      struct registers *regs, void *call_data,
+                      const char *fmt, ...)
 {
        va_list args;
 
        va_start(args, fmt);
-       ltt_vtrace(mdata, probe_data, call_data, fmt, &args);
+       ltt_vtrace(mdata, probe_data, regs, call_data, fmt, &args);
        va_end(args);
 }
 
index 3d3bd485dffb51345007a128f37d188874be84ca..e28b3159d73c1408b58b072850f2bb89a45d59eb 100644 (file)
@@ -117,7 +117,7 @@ static void print_markers(FILE *fp)
        marker_iter_start(&iter);
 
        while(iter.marker) {
-               fprintf(fp, "marker: %s/%s %d \"%s\"\n", iter.marker->channel, iter.marker->name, (int)imv_read(iter.marker->state), iter.marker->format);
+               fprintf(fp, "marker: %s/%s %d \"%s\" %p\n", iter.marker->channel, iter.marker->name, (int)imv_read(iter.marker->state), iter.marker->format, iter.marker->location);
                marker_iter_next(&iter);
        }
        unlock_markers();
@@ -837,7 +837,7 @@ static void auto_probe_connect(struct marker *m)
        if(result && result != -EEXIST)
                ERR("ltt_marker_connect (marker = %s/%s, errno = %d)", m->channel, m->name, -result);
 
-       DBG("auto connected marker %s %s to probe default", m->channel, m->name);
+       DBG("auto connected marker %s (addr: %p) %s to probe default", m->channel, m, m->name);
 
 }
 
index cb84dad7e05332725a20a54b65b6d2cf9b82a9e3..502cdcce436b763e4ba06c7a6cfe00c55e6a54ed 100644 (file)
@@ -110,9 +110,9 @@ struct ltt_active_marker {
 
 struct marker; //ust//
 extern void ltt_vtrace(const struct marker *mdata, void *probe_data,
-       void *call_data, const char *fmt, va_list *args);
+       struct registers *regs, void *call_data, const char *fmt, va_list *args);
 extern void ltt_trace(const struct marker *mdata, void *probe_data,
-       void *call_data, const char *fmt, ...);
+       struct registers *regs, void *call_data, const char *fmt, ...);
 
 /*
  * Unique ID assigned to each registered probe.
index 0026c3b12a88816392df29447289d48404656d16..bfa6352e1ccf2b4063660ff279b007f29ec3702a 100644 (file)
@@ -541,6 +541,24 @@ void sigterm_handler(int sig)
        terminate_req = 1;
 }
 
+static int write_pidfile(const char *file_name, pid_t pid)
+{
+       FILE *pidfp;
+
+       pidfp = fopen(file_name, "w+");
+       if(!pidfp) {
+               PERROR("fopen (%s)", pidfile);
+               WARN("killing child process");
+               return -1;
+       }
+
+       fprintf(pidfp, "%d\n", pid);
+
+       fclose(pidfp);
+
+       return 0;
+}
+
 int start_ustd(int fd)
 {
        struct ustcomm_ustd ustd;
@@ -585,6 +603,15 @@ int start_ustd(int fd)
                return 1;
        }
 
+       /* Write pidfile */
+       if(pidfile) {
+               result = write_pidfile(pidfile, getpid());
+               if(result == -1) {
+                       ERR("failed to write pidfile");
+                       return 1;
+               }
+       }
+
        /* Notify parent that we are successfully started. */
        if(fd != -1) {
                /* write any one character */
@@ -673,26 +700,6 @@ int start_ustd_daemon()
                char buf;
                FILE *pidfp;
 
-               /* It's important to write the file *before*
-                * the parent ends, because the file may be
-                * read as soon as the parent ends.
-                */
-               if(pidfile) {
-                       pidfp = fopen(pidfile, "w+");
-                       if(!pidfp) {
-                               PERROR("fopen (%s)", pidfile);
-                               WARN("killing child process");
-                               result = kill(child_pid, SIGTERM);
-                               if(result == -1) {
-                                       PERROR("kill");
-                               }
-                               return -1;
-                       }
-
-                       fprintf(pidfp, "%d\n", child_pid);
-                       fclose(pidfp);
-               }
-
                result = read(fd[0], &buf, 1);
                if(result == -1) {
                        PERROR("read");
index fe8a5cd8f8c47f80a53a72164c1ac8852d20a1a3..52c378dfbd12041636f1630e7b82d49ee51bcbb6 100755 (executable)
--- a/usttrace
+++ b/usttrace
@@ -78,9 +78,9 @@ SOCKPATH="/tmp/ust-sock-$$"
 if [ "$arg_syswide_daemon" != "1" ];
 then
        pidfilepath="/tmp/usttrace-$USER-$(date +%Y%m%d%H%M%S%N)-ustd-pid"
-
+       mkfifo -m 0600 "$pidfilepath"
        # Start daemon
-       $USTD -d --pidfile "$pidfilepath" -s "$SOCKPATH" -o "$OUTDIR" >"$OUTDIR/ustd.log" 2>&1 &
+       $USTD --pidfile "$pidfilepath" -s "$SOCKPATH" -o "$OUTDIR" >"$OUTDIR/ustd.log" 2>&1 &
        USTDPID="$(<$pidfilepath)"
        export UST_DAEMON_SOCKET="$SOCKPATH"
 fi
@@ -129,7 +129,7 @@ then
        kill -SIGTERM "$USTDPID"
 
        echo "Waiting for ustd to shutdown..."
-       wait "$USTDPID"
+       wait "$(USTDPID)"
 
        rm "$pidfilepath"
 fi
This page took 0.031703 seconds and 4 git commands to generate.