user_myfacility.myevent: 39507.805584526 (/cpu_1), 15829, 15736, SYSCALL { "myapp.c", "main", 8, 1234, 0xf0f0f0f0 }
+* Fun feature : function instrumentation
+
+Here is how to generate a full trace of you program function calls.
+See the sample-instrument-fct.c example program.
+
+- Compile your application with at least these parameters to gcc (it is splitted
+ on two lines, joined by a "\") :
+gcc -g -I /usr/src/usertrace-generic -o myapp myapp.c \
+ /usr/src/usertrace-generic/ltt-facility-loader-user_myfacility.c \
+ /usr/src/usertrace-generic/ltt-instrument-functions.c
+
+To see what the final result looks like :
+- Start tracing
+- Start your application
+- Stop tracing
+Then, to see only the function_entry and function_exit events :
+lttv -m textDump -t /tmp/trace1 -e "event.facility=user_generic & (event.name=function_entry & event.name=function_exit)"
+
+It will show, for example :
+user_generic.function_entry: 59329.709939111 (/cpu_0), 19250, 18581, SYSCALL {
+0x8048454, 0x80484c2 }
+user_generic.function_exit: 59329.709944613 (/cpu_0), 19250, 18581, SYSCALL { 0
+x8048454, 0x80484c2 }
+
+you can then use (from the binutils package)
+addr2line -e sample-instrument-fct -i -f 0x8048454
+Which shows :
+test_function
+/usr/src/usertrace-generic/sample-instrument-fct.c:12
+
+The lookup in LTTV through libbfd has not been implemented yet.
+
*len = 0;
}
- ret = ltt_trace_generic(ltt_facility_user_generic_FB850A80, event_user_generic_string, buffer, reserve_size, LTT_BLOCKING);
+ ret = ltt_trace_generic(ltt_facility_user_generic_F583779E, event_user_generic_string, buffer, reserve_size, LTT_BLOCKING);
}
return ret;
*len = 0;
}
- ret = ltt_trace_generic(ltt_facility_user_generic_FB850A80, event_user_generic_string_pointer, buffer, reserve_size, LTT_BLOCKING);
+ ret = ltt_trace_generic(ltt_facility_user_generic_F583779E, event_user_generic_string_pointer, buffer, reserve_size, LTT_BLOCKING);
}
return ret;
#else
{
int ret = 0;
- reserve_size += ltt_align(reserve_size, sizeof(void *));
+ reserve_size = ltt_align(reserve_size, sizeof(void *));
{
- ret = ltt_trace_generic(ltt_facility_user_generic_FB850A80, event_user_generic_slow_printf, buffer, reserve_size, LTT_BLOCKING);
+ ret = ltt_trace_generic(ltt_facility_user_generic_F583779E, event_user_generic_slow_printf, buffer, reserve_size, LTT_BLOCKING);
+ }
+
+ return ret;
+
+}
+#endif //LTT_TRACE
+
+/* Event function_entry structures */
+
+/* Event function_entry logging function */
+static inline __attribute__((no_instrument_function)) int trace_user_generic_function_entry(
+ const void * lttng_param_this_fn,
+ const void * lttng_param_call_site)
+#ifndef LTT_TRACE
+{
+}
+#else
+{
+ int ret = 0;
+ void *buffer = NULL;
+ size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+ size_t *to_base = &real_to_base;
+ size_t real_to = 0;
+ size_t *to = &real_to;
+ size_t real_len = 0;
+ size_t *len = &real_len;
+ size_t reserve_size;
+ size_t slot_size;
+ size_t align;
+ const void *real_from;
+ const void **from = &real_from;
+ /* For each field, calculate the field size. */
+ /* size = *to_base + *to + *len */
+ /* Assume that the padding for alignment starts at a
+ * sizeof(void *) address. */
+
+ *from = <tng_param_this_fn;
+ align = sizeof(const void *);
+
+ if(*len == 0) {
+ *to += ltt_align(*to, align); /* align output */
+ } else {
+ *len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+ }
+
+ *len += sizeof(const void *);
+
+ *from = <tng_param_call_site;
+ align = sizeof(const void *);
+
+ if(*len == 0) {
+ *to += ltt_align(*to, align); /* align output */
+ } else {
+ *len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+ }
+
+ *len += sizeof(const void *);
+
+ reserve_size = *to_base + *to + *len;
+ {
+ char stack_buffer[reserve_size];
+ buffer = stack_buffer;
+
+ *to_base = *to = *len = 0;
+
+ *from = <tng_param_this_fn;
+ align = sizeof(const void *);
+
+ if(*len == 0) {
+ *to += ltt_align(*to, align); /* align output */
+ } else {
+ *len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+ }
+
+ *len += sizeof(const void *);
+
+ /* Flush pending memcpy */
+ if(*len != 0) {
+ memcpy(buffer+*to_base+*to, *from, *len);
+ *to += *len;
+ *len = 0;
+ }
+
+ *from = <tng_param_call_site;
+ align = sizeof(const void *);
+
+ if(*len == 0) {
+ *to += ltt_align(*to, align); /* align output */
+ } else {
+ *len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+ }
+
+ *len += sizeof(const void *);
+
+ /* Flush pending memcpy */
+ if(*len != 0) {
+ memcpy(buffer+*to_base+*to, *from, *len);
+ *to += *len;
+ *len = 0;
+ }
+
+ ret = ltt_trace_generic(ltt_facility_user_generic_F583779E, event_user_generic_function_entry, buffer, reserve_size, LTT_BLOCKING);
+ }
+
+ return ret;
+
+}
+#endif //LTT_TRACE
+
+/* Event function_exit structures */
+
+/* Event function_exit logging function */
+static inline __attribute__((no_instrument_function)) int trace_user_generic_function_exit(
+ const void * lttng_param_this_fn,
+ const void * lttng_param_call_site)
+#ifndef LTT_TRACE
+{
+}
+#else
+{
+ int ret = 0;
+ void *buffer = NULL;
+ size_t real_to_base = 0; /* The buffer is allocated on arch_size alignment */
+ size_t *to_base = &real_to_base;
+ size_t real_to = 0;
+ size_t *to = &real_to;
+ size_t real_len = 0;
+ size_t *len = &real_len;
+ size_t reserve_size;
+ size_t slot_size;
+ size_t align;
+ const void *real_from;
+ const void **from = &real_from;
+ /* For each field, calculate the field size. */
+ /* size = *to_base + *to + *len */
+ /* Assume that the padding for alignment starts at a
+ * sizeof(void *) address. */
+
+ *from = <tng_param_this_fn;
+ align = sizeof(const void *);
+
+ if(*len == 0) {
+ *to += ltt_align(*to, align); /* align output */
+ } else {
+ *len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+ }
+
+ *len += sizeof(const void *);
+
+ *from = <tng_param_call_site;
+ align = sizeof(const void *);
+
+ if(*len == 0) {
+ *to += ltt_align(*to, align); /* align output */
+ } else {
+ *len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+ }
+
+ *len += sizeof(const void *);
+
+ reserve_size = *to_base + *to + *len;
+ {
+ char stack_buffer[reserve_size];
+ buffer = stack_buffer;
+
+ *to_base = *to = *len = 0;
+
+ *from = <tng_param_this_fn;
+ align = sizeof(const void *);
+
+ if(*len == 0) {
+ *to += ltt_align(*to, align); /* align output */
+ } else {
+ *len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+ }
+
+ *len += sizeof(const void *);
+
+ /* Flush pending memcpy */
+ if(*len != 0) {
+ memcpy(buffer+*to_base+*to, *from, *len);
+ *to += *len;
+ *len = 0;
+ }
+
+ *from = <tng_param_call_site;
+ align = sizeof(const void *);
+
+ if(*len == 0) {
+ *to += ltt_align(*to, align); /* align output */
+ } else {
+ *len += ltt_align(*to+*len, align); /* alignment, ok to do a memcpy of it */
+ }
+
+ *len += sizeof(const void *);
+
+ /* Flush pending memcpy */
+ if(*len != 0) {
+ memcpy(buffer+*to_base+*to, *from, *len);
+ *to += *len;
+ *len = 0;
+ }
+
+ ret = ltt_trace_generic(ltt_facility_user_generic_F583779E, event_user_generic_function_exit, buffer, reserve_size, LTT_BLOCKING);
}
return ret;
size_t size_t_size;
};
-static inline _syscall5(int, ltt_trace_generic, unsigned int, facility_id,
- unsigned int, event_id, void *, data, size_t, data_size, int, blocking)
-static inline _syscall2(int, ltt_register_generic, unsigned int *, facility_id, const struct user_facility_info *, info)
+static inline __attribute__((no_instrument_function))
+_syscall5(int, ltt_trace_generic, unsigned int, facility_id,
+ unsigned int, event_id, void *, data, size_t, data_size, int, blocking)
+static inline __attribute__((no_instrument_function))
+_syscall2(int, ltt_register_generic, unsigned int *, facility_id,
+ const struct user_facility_info *, info)
#ifndef LTT_PACK
/* Calculate the offset needed to align the type */
-static inline unsigned int ltt_align(size_t align_drift,
- size_t size_of_type)
+static inline unsigned int __attribute__((no_instrument_function))
+ ltt_align(size_t align_drift,
+ size_t size_of_type)
{
size_t alignment = min(sizeof(void*), size_of_type);
return ((alignment - align_drift) & (alignment-1));
}
#else
-static inline unsigned int ltt_align(size_t align_drift,
- size_t size_of_type)
+static inline unsigned int __attribute__((no_instrument_function))
+ ltt_align(size_t align_drift,
+ size_t size_of_type)
{
return 0;
}