[sheepdog] [PATCH v3 06/10] add notrace to only entry point and exit point
MORITA Kazutaka
morita.kazutaka at gmail.com
Fri Aug 9 11:09:03 CEST 2013
From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
It is difficult to know which function needs a notrace directive. We
are using notrace to avoid starting tracer recursively while tracing,
but we can do the similar thing by using a thread local variable.
With this patch, notrace is necessary only to the entry point
(trace_function_enter) and the exit point (trace_function_exit). This
patch removes notrace compiler.h so that we don't abuse the directive
any more.
This patch also allows us to use tracer with debug build.
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
include/compiler.h | 1 -
include/list.h | 1 -
lib/logger.c | 40 ++++++++++++++++++++--------------------
lib/net.c | 4 ++--
lib/strbuf.c | 4 ++--
lib/util.c | 4 ++--
sheep/trace/graph.c | 6 +++---
sheep/trace/trace.c | 50 +++++++++++++++++++++++++++++++++-----------------
8 files changed, 62 insertions(+), 48 deletions(-)
diff --git a/include/compiler.h b/include/compiler.h
index b2ae002..df38dc8 100644
--- a/include/compiler.h
+++ b/include/compiler.h
@@ -12,7 +12,6 @@
#ifndef SD_COMPILER_H
#define SD_COMPILER_H
-#define notrace __attribute__((no_instrument_function))
#define __packed __attribute((packed))
#define __printf(a, b) __attribute__((format(printf, a, b)))
diff --git a/include/list.h b/include/list.h
index c8ee425..44db5a6 100644
--- a/include/list.h
+++ b/include/list.h
@@ -164,7 +164,6 @@ static inline int hlist_unhashed(const struct hlist_node *h)
return !h->pprev;
}
-__attribute__((always_inline))
static inline int hlist_empty(const struct hlist_head *h)
{
return !h->first;
diff --git a/lib/logger.c b/lib/logger.c
index 2bae1bd..a3ea11e 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -135,7 +135,7 @@ init_log_formatter(void)
exit(1);
}
-static notrace int logarea_init(int size)
+static int logarea_init(int size)
{
int shmid;
@@ -196,7 +196,7 @@ static notrace int logarea_init(int size)
return 0;
}
-static void notrace free_logarea(void)
+static void free_logarea(void)
{
if (log_fd >= 0)
close(log_fd);
@@ -205,7 +205,7 @@ static void notrace free_logarea(void)
shmdt(la);
}
-static notrace int server_log_formatter(char *buff, size_t size,
+static int server_log_formatter(char *buff, size_t size,
const struct logmsg *msg)
{
char *p = buff;
@@ -251,7 +251,7 @@ static notrace int server_log_formatter(char *buff, size_t size,
}
log_format_register("server", server_log_formatter);
-static notrace int default_log_formatter(char *buff, size_t size,
+static int default_log_formatter(char *buff, size_t size,
const struct logmsg *msg)
{
int len;
@@ -265,7 +265,7 @@ static notrace int default_log_formatter(char *buff, size_t size,
}
log_format_register("default", default_log_formatter);
-static notrace int json_log_formatter(char *buff, size_t size,
+static int json_log_formatter(char *buff, size_t size,
const struct logmsg *msg)
{
int i, body_len;
@@ -332,7 +332,7 @@ static notrace int json_log_formatter(char *buff, size_t size,
log_format_register("json", json_log_formatter);
/* this one can block under memory pressure */
-static notrace void log_syslog(const struct logmsg *msg)
+static void log_syslog(const struct logmsg *msg)
{
char str[MAX_MSG_SIZE];
@@ -344,7 +344,7 @@ static notrace void log_syslog(const struct logmsg *msg)
syslog(msg->prio, "%s", str);
}
-static notrace void init_logmsg(struct logmsg *msg, struct timeval *tv,
+static void init_logmsg(struct logmsg *msg, struct timeval *tv,
int prio, const char *func, int line)
{
msg->tv = *tv;
@@ -356,7 +356,7 @@ static notrace void init_logmsg(struct logmsg *msg, struct timeval *tv,
msg->worker_idx = worker_idx;
}
-static notrace void dolog(int prio, const char *func, int line,
+static void dolog(int prio, const char *func, int line,
const char *fmt, va_list ap)
{
char buf[sizeof(struct logmsg) + MAX_MSG_SIZE];
@@ -412,7 +412,7 @@ static notrace void dolog(int prio, const char *func, int line,
}
}
-static notrace void rotate_log(void)
+static void rotate_log(void)
{
int new_fd;
@@ -441,7 +441,7 @@ static notrace void rotate_log(void)
close(new_fd);
}
-notrace void log_write(int prio, const char *func, int line, const char *fmt, ...)
+void log_write(int prio, const char *func, int line, const char *fmt, ...)
{
va_list ap;
@@ -453,7 +453,7 @@ notrace void log_write(int prio, const char *func, int line, const char *fmt, ..
va_end(ap);
}
-static notrace void log_flush(void)
+static void log_flush(void)
{
struct sembuf ops;
size_t size, done = 0;
@@ -493,7 +493,7 @@ static bool is_sheep_dead(int signo)
return signo == SIGHUP;
}
-static notrace void crash_handler(int signo)
+static void crash_handler(int signo)
{
if (is_sheep_dead(signo))
sd_printf(SDOG_ERR, "sheep pid %d exited unexpectedly.",
@@ -515,7 +515,7 @@ static notrace void crash_handler(int signo)
reraise_crash_signal(signo, 1);
}
-static notrace void logger(char *log_dir, char *outfile)
+static void logger(char *log_dir, char *outfile)
{
int fd;
@@ -605,7 +605,7 @@ void early_log_init(const char *format_name, struct logger_user_info *user_info)
exit(1);
}
-notrace int log_init(const char *program_name, bool to_stdout, int level,
+int log_init(const char *program_name, bool to_stdout, int level,
char *outfile)
{
char log_dir[PATH_MAX], tmp[PATH_MAX];
@@ -651,7 +651,7 @@ notrace int log_init(const char *program_name, bool to_stdout, int level,
return 0;
}
-notrace void log_close(void)
+void log_close(void)
{
if (la) {
la->active = false;
@@ -663,14 +663,14 @@ notrace void log_close(void)
}
}
-notrace void set_thread_name(const char *name, bool show_idx)
+void set_thread_name(const char *name, bool show_idx)
{
worker_name = name;
if (show_idx)
worker_idx = gettid();
}
-notrace void get_thread_name(char *name)
+void get_thread_name(char *name)
{
if (worker_name && worker_idx)
snprintf(name, MAX_THREAD_NAME_LEN, "%s %d",
@@ -713,7 +713,7 @@ static bool check_gdb(void)
#define FRAME_POINTER ((unsigned long *)__builtin_frame_address(0) + 2)
__attribute__ ((__noinline__))
-notrace int __sd_dump_variable(const char *var)
+int __sd_dump_variable(const char *var)
{
char cmd[ARG_MAX], path[PATH_MAX], info[256];
FILE *f = NULL;
@@ -759,7 +759,7 @@ notrace int __sd_dump_variable(const char *var)
}
__attribute__ ((__noinline__))
-static notrace int dump_stack_frames(void)
+static int dump_stack_frames(void)
{
char path[PATH_MAX];
int i, stack_no = 0;
@@ -826,7 +826,7 @@ static notrace int dump_stack_frames(void)
}
__attribute__ ((__noinline__))
-notrace void sd_backtrace(void)
+void sd_backtrace(void)
{
void *addrs[SD_MAX_STACK_DEPTH];
int i, n = backtrace(addrs, ARRAY_SIZE(addrs));
diff --git a/lib/net.c b/lib/net.c
index 30d0119..c673ad8 100644
--- a/lib/net.c
+++ b/lib/net.c
@@ -61,7 +61,7 @@ int conn_rx_on(struct connection *conn)
return modify_event(conn->fd, conn->events);
}
-notrace bool is_conn_dead(const struct connection *conn)
+bool is_conn_dead(const struct connection *conn)
{
if (conn->c_rx_state == C_IO_CLOSED || conn->c_tx_state == C_IO_CLOSED)
return true;
@@ -94,7 +94,7 @@ int rx(struct connection *conn, enum conn_state next_state)
return ret;
}
-notrace int tx(struct connection *conn, enum conn_state next_state)
+int tx(struct connection *conn, enum conn_state next_state)
{
int ret;
diff --git a/lib/strbuf.c b/lib/strbuf.c
index 28ed38c..4a41d4d 100644
--- a/lib/strbuf.c
+++ b/lib/strbuf.c
@@ -50,7 +50,7 @@ void strbuf_attach(struct strbuf *sb, void *buf, size_t len, size_t alloc)
sb->buf[sb->len] = '\0';
}
-notrace void strbuf_grow(struct strbuf *sb, size_t extra)
+void strbuf_grow(struct strbuf *sb, size_t extra)
{
if (sb->len + extra + 1 <= sb->len)
panic("you want to use way too much memory");
@@ -98,7 +98,7 @@ void strbuf_remove(struct strbuf *sb, size_t pos, size_t len)
strbuf_splice(sb, pos, len, NULL, 0);
}
-notrace void strbuf_add(struct strbuf *sb, const void *data, size_t len)
+void strbuf_add(struct strbuf *sb, const void *data, size_t len)
{
strbuf_grow(sb, len);
memcpy(sb->buf + sb->len, data, len);
diff --git a/lib/util.c b/lib/util.c
index ff0eafb..560999c 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -64,7 +64,7 @@ void *xzalloc(size_t size)
return xcalloc(1, size);
}
-notrace void *xrealloc(void *ptr, size_t size)
+void *xrealloc(void *ptr, size_t size)
{
void *ret = realloc(ptr, size);
if (!ret && !size)
@@ -316,7 +316,7 @@ void eventfd_xwrite(int efd, int value)
* @param buf_size size of destination buffer
* @param str source string
*/
-void notrace pstrcpy(char *buf, int buf_size, const char *str)
+void pstrcpy(char *buf, int buf_size, const char *str)
{
int c;
char *q = buf;
diff --git a/sheep/trace/graph.c b/sheep/trace/graph.c
index 2dafd22..f3f0858 100644
--- a/sheep/trace/graph.c
+++ b/sheep/trace/graph.c
@@ -15,7 +15,7 @@
static __thread unsigned long long entry_time[SD_MAX_STACK_DEPTH];
-static notrace uint64_t clock_get_time(void)
+static uint64_t clock_get_time(void)
{
struct timespec ts;
@@ -23,7 +23,7 @@ static notrace uint64_t clock_get_time(void)
return (uint64_t)ts.tv_sec * 1000000000LL + (uint64_t)ts.tv_nsec;
}
-static notrace void graph_tracer_exit(const struct caller *this_fn, int depth)
+static void graph_tracer_exit(const struct caller *this_fn, int depth)
{
struct trace_graph_item trace = {
.depth = depth,
@@ -37,7 +37,7 @@ static notrace void graph_tracer_exit(const struct caller *this_fn, int depth)
trace_buffer_push(sched_getcpu(), &trace);
}
-static notrace void graph_tracer_enter(const struct caller *this_fn, int depth)
+static void graph_tracer_enter(const struct caller *this_fn, int depth)
{
struct trace_graph_item trace = {
.type = TRACE_GRAPH_ENTRY,
diff --git a/sheep/trace/trace.c b/sheep/trace/trace.c
index 9f9420f..67fa95e 100644
--- a/sheep/trace/trace.c
+++ b/sheep/trace/trace.c
@@ -32,6 +32,8 @@ static struct strbuf *buffer;
static pthread_mutex_t *buffer_lock;
static int nr_cpu;
+static __thread bool in_trace;
+
union instruction {
unsigned char start[INSN_SIZE];
struct {
@@ -40,12 +42,12 @@ union instruction {
} __attribute__((packed));
};
-static notrace int caller_cmp(const struct caller *a, const struct caller *b)
+static int caller_cmp(const struct caller *a, const struct caller *b)
{
return intcmp(a->mcount, b->mcount);
}
-static notrace unsigned char *get_new_call(unsigned long ip, unsigned long addr)
+static unsigned char *get_new_call(unsigned long ip, unsigned long addr)
{
static union instruction code;
@@ -55,7 +57,7 @@ static notrace unsigned char *get_new_call(unsigned long ip, unsigned long addr)
return code.start;
}
-static notrace void replace_call(unsigned long ip, unsigned long func)
+static void replace_call(unsigned long ip, unsigned long func)
{
unsigned char *new;
@@ -63,14 +65,14 @@ static notrace void replace_call(unsigned long ip, unsigned long func)
memcpy((void *)ip, new, INSN_SIZE);
}
-static notrace int make_text_writable(unsigned long ip)
+static int make_text_writable(unsigned long ip)
{
unsigned long start = ip & ~(getpagesize() - 1);
return mprotect((void *)start, getpagesize() + INSN_SIZE, PROT_READ | PROT_EXEC | PROT_WRITE);
}
-static notrace struct caller *trace_lookup_ip(unsigned long ip)
+static struct caller *trace_lookup_ip(unsigned long ip)
{
const struct caller key = {
.mcount = ip,
@@ -79,29 +81,35 @@ static notrace struct caller *trace_lookup_ip(unsigned long ip)
return xbsearch(&key, callers, nr_callers, caller_cmp);
}
-notrace void regist_tracer(struct tracer *tracer)
+void regist_tracer(struct tracer *tracer)
{
list_add_tail(&tracer->list, &tracers);
}
-static notrace void patch_all_sites(unsigned long addr)
+static void patch_all_sites(unsigned long addr)
{
for (int i = 0; i < nr_callers; i++)
replace_call(callers[i].mcount, addr);
}
-static notrace void nop_all_sites(void)
+static void nop_all_sites(void)
{
for (int i = 0; i < nr_callers; i++)
memcpy((void *)callers[i].mcount, NOP5, INSN_SIZE);
}
/* the entry point of the function */
-notrace void trace_function_enter(unsigned long ip, unsigned long *ret_addr)
+__attribute__((no_instrument_function))
+void trace_function_enter(unsigned long ip, unsigned long *ret_addr)
{
struct tracer *tracer;
const struct caller *caller;
+ if (in_trace)
+ /* don't trace while tracing */
+ return;
+ in_trace = true;
+
assert(ret_stack_index < ARRAY_SIZE(trace_ret_stack));
caller = trace_lookup_ip(ip);
@@ -115,13 +123,19 @@ notrace void trace_function_enter(unsigned long ip, unsigned long *ret_addr)
trace_ret_stack[ret_stack_index].ret = *ret_addr;
ret_stack_index++;
*ret_addr = (unsigned long)trace_return_caller;
+
+ in_trace = false;
}
/* the exit point of the function */
-notrace unsigned long trace_function_exit(void)
+__attribute__((no_instrument_function))
+unsigned long trace_function_exit(void)
{
struct tracer *tracer;
+ assert(!in_trace);
+ in_trace = true;
+
ret_stack_index--;
list_for_each_entry(tracer, &tracers, list) {
@@ -130,10 +144,12 @@ notrace unsigned long trace_function_exit(void)
ret_stack_index);
}
+ in_trace = false;
+
return trace_ret_stack[ret_stack_index].ret;
}
-static notrace size_t count_enabled_tracers(void)
+static size_t count_enabled_tracers(void)
{
size_t nr = 0;
struct tracer *t;
@@ -146,7 +162,7 @@ static notrace size_t count_enabled_tracers(void)
return nr;
}
-static notrace struct tracer *find_tracer(const char *name)
+static struct tracer *find_tracer(const char *name)
{
struct tracer *t;
@@ -158,7 +174,7 @@ static notrace struct tracer *find_tracer(const char *name)
return NULL;
}
-notrace int trace_enable(const char *name)
+int trace_enable(const char *name)
{
struct tracer *tracer = find_tracer(name);
@@ -182,7 +198,7 @@ notrace int trace_enable(const char *name)
return SD_RES_SUCCESS;
}
-notrace int trace_disable(const char *name)
+int trace_disable(const char *name)
{
struct tracer *tracer = find_tracer(name);
@@ -205,7 +221,7 @@ notrace int trace_disable(const char *name)
return SD_RES_SUCCESS;
}
-notrace int trace_buffer_pop(void *buf, uint32_t len)
+int trace_buffer_pop(void *buf, uint32_t len)
{
int readin, count = 0, requested = len;
char *buff = (char *)buf;
@@ -228,7 +244,7 @@ notrace int trace_buffer_pop(void *buf, uint32_t len)
return count;
}
-notrace void trace_buffer_push(int cpuid, struct trace_graph_item *item)
+void trace_buffer_push(int cpuid, struct trace_graph_item *item)
{
pthread_mutex_lock(&buffer_lock[cpuid]);
strbuf_add(&buffer[cpuid], item, sizeof(*item));
@@ -347,7 +363,7 @@ static int init_callers(void)
* Try to NOP all the mcount call sites that are supposed to be traced. Later
* we can enable it by asking these sites to point to trace_caller.
*/
-notrace int trace_init(void)
+int trace_init(void)
{
int i;
--
1.7.9.5
More information about the sheepdog
mailing list