[sheepdog] [PATCH v2] sheep: use gcc builtin to get stack frame pointer
Liu Yuan
namei.unix at gmail.com
Wed Jul 31 08:51:41 CEST 2013
This remove hardcoded assembly which is not portable.
Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
include/logger.h | 5 ++---
lib/logger.c | 26 +++++++++++++++++++-------
2 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/include/logger.h b/include/logger.h
index 79eb108..9253548 100644
--- a/include/logger.h
+++ b/include/logger.h
@@ -39,10 +39,9 @@ void set_thread_name(const char *name, bool show_idx);
void get_thread_name(char *name);
#define sd_dump_variable(var) ({ \
- register void *current_sp asm("rsp"); \
- __sd_dump_variable(#var, current_sp); \
+ __sd_dump_variable(#var); \
})
-int __sd_dump_variable(const char *var, const void *base_sp);
+int __sd_dump_variable(const char *var);
void sd_backtrace(void);
/* sheep log priorities, comliant with syslog spec */
diff --git a/lib/logger.c b/lib/logger.c
index 253163d..2bae1bd 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -697,11 +697,27 @@ static bool check_gdb(void)
return system("which gdb > /dev/null") == 0;
}
+/*
+ * __builtin_frame_address() returns address in frame pointer register if any
+ * (e.g, in x86 it returns EBP). If no dedicated register, the frame address is
+ * normally the address of the first word pushed on to the stack by the function
+ *
+ * For a normal subroutine setup, above the value __builtin_frame_address
+ * returns, there are two addresses, which stores old EBP and old EIP, being
+ * pushed on to the stack. So we have to plus 2 to get the right value for the
+ * frame address, which is expected by GDB.
+ *
+ * This is tested on X86, other architetures aren't tested. But even if this
+ * formula is wrong, GDB just doesn't procude anything useful after panic.
+ */
+#define FRAME_POINTER ((unsigned long *)__builtin_frame_address(0) + 2)
+
__attribute__ ((__noinline__))
-notrace int __sd_dump_variable(const char *var, const void *base_sp)
+notrace int __sd_dump_variable(const char *var)
{
char cmd[ARG_MAX], path[PATH_MAX], info[256];
FILE *f = NULL;
+ void *base_sp = FRAME_POINTER;
if (!check_gdb()) {
sd_dprintf("cannot find gdb");
@@ -742,16 +758,12 @@ notrace int __sd_dump_variable(const char *var, const void *base_sp)
return 0;
}
-#define dump_stack_frames() ({ \
- register void *current_sp asm("rsp"); \
- __dump_stack_frames(current_sp); \
-})
-
__attribute__ ((__noinline__))
-static notrace int __dump_stack_frames(const void *base_sp)
+static notrace int dump_stack_frames(void)
{
char path[PATH_MAX];
int i, stack_no = 0;
+ void *base_sp = FRAME_POINTER;
if (!check_gdb()) {
sd_dprintf("cannot find gdb");
--
1.7.9.5
More information about the sheepdog
mailing list