This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Tarantool -- an efficient key/value data store".

The branch core-save-rbp has been updated
       via  ee903572a8c143ee31e4941e9e4c0e62b708eb5a (commit)
       via  93a5ba7d5c1edf690e4e97e61b8f0a44ea0de559 (commit)
      from  4e2a054c745a6bc87637df0b2dbc7b213e5a4fa5 (commit)

Summary of changes:
 core/Makefile        |    5 ++
 core/fiber.c         |   21 ++++++---
 core/log_io_remote.c |    4 +-
 core/tarantool.c     |    4 ++
 core/util.c          |  116 +++++++++++++++++++++++++++++++++++++++++++++++++-
 include/util.h       |   26 +++++++----
 6 files changed, 155 insertions(+), 21 deletions(-)

commit ee903572a8c143ee31e4941e9e4c0e62b708eb5a
Author: Yuriy Vostrikov <[email protected]>
Date:   Mon Dec 13 13:27:51 2010 +0300

    [core] Print symbols in backtraces.

diff --git a/core/Makefile b/core/Makefile
index 1a41b17..3241278 100644
--- a/core/Makefile
+++ b/core/Makefile
@@ -21,6 +21,11 @@ core/tarantool_ev.o: CFLAGS += -U_FORTIFY_SOURCE \
                              -Wno-parentheses \
                              -Wno-unused
 
+ifeq (1,$(RESOLVE_SYMBOLS))
+ LDFLAGS += -rdynamic -lbfd
+ CFLAGS += -DRESOLVE_SYMBOLS
+endif
+
 ifneq (,$(TRACE))
  obj += core/trace.o
  $(TRACE): CFLAGS += -finstrument-functions
diff --git a/core/fiber.c b/core/fiber.c
index e3e32a4..8968c3e 100644
--- a/core/fiber.c
+++ b/core/fiber.c
@@ -87,9 +87,7 @@ fiber_msg(const struct tbuf *buf)
 }
 
 KHASH_MAP_INIT_INT(fid2fiber, void *, realloc);
-static
-khash_t(fid2fiber) *
-    fibers_registry;
+static khash_t(fid2fiber) *fibers_registry;
 
 void
 fiber_call(struct fiber *callee)
@@ -1036,10 +1034,12 @@ fiber_server(fiber_server_type type, int port, void 
(*handler) (void *data), voi
        return s;
 }
 
+
 void
 fiber_info(struct tbuf *out)
 {
        struct fiber *fiber;
+
        tbuf_printf(out, "fibers:\n");
        SLIST_FOREACH(fiber, &fibers, link) {
                void *stack_top = fiber->coro.stack + fiber->coro.stack_size;
@@ -1052,16 +1052,21 @@ fiber_info(struct tbuf *out)
                tbuf_printf(out, "    peer: %s\n", fiber_peer_name(fiber));
                tbuf_printf(out, "    stack: %p\n", stack_top);
 
-#if CORO_ASM
+#if defined(__x86) || defined (__amd64) || defined(__i386)
                tbuf_printf(out, "    exc: %p, frame: %p\n", ((void 
**)fiber->exc)[3], ((void **)fiber->exc)[3] + 2 * sizeof(void *));
 
                void *stack_bottom = fiber->coro.stack;
-
                struct frame *frame = fiber->rbp;
                tbuf_printf(out, "    backtrace:\n");
                while (stack_bottom < (void *)frame && (void *)frame < 
stack_top) {
-                       tbuf_printf(out, "        - { rbp: %p, frame: %p, pc: 
%p }\n",
+                       tbuf_printf(out, "        - { rbp: %p, frame: %p, pc: 
%p",
                                    frame, (void *)frame + 2 * sizeof(void *), 
frame->ret);
+#ifdef RESOLVE_SYMBOLS
+                       struct fsym *s = addr2sym(frame->ret);
+                       if (s)
+                               tbuf_printf(out, " <%s+%i>", s->name, 
frame->ret - s->addr);
+#endif
+                       tbuf_printf(out, " }\n");
                        frame = frame->rbp;
                }
 #endif
diff --git a/core/log_io_remote.c b/core/log_io_remote.c
index e3d347f..3495782 100644
--- a/core/log_io_remote.c
+++ b/core/log_io_remote.c
@@ -51,7 +51,7 @@ row_v11_len(struct tbuf *r)
 }
 
 static struct tbuf *
-row_reader_v11()
+remote_row_reader_v11()
 {
        const int header_size = sizeof(struct row_v11);
        struct tbuf *m;
@@ -107,7 +107,7 @@ remote_read_row(i64 initial_lsn)
                        err = NULL;
                }
 
-               row = row_reader_v11(fiber->pool);
+               row = remote_row_reader_v11(fiber->pool);
                if (row == NULL) {
                        err = "can't read row";
                        goto err;
diff --git a/core/tarantool.c b/core/tarantool.c
index 061e9f6..908562e 100644
--- a/core/tarantool.c
+++ b/core/tarantool.c
@@ -69,6 +69,7 @@ tarantool_version(void)
 }
 
 static double start_time;
+
 double
 tarantool_uptime(void)
 {
@@ -442,6 +443,9 @@ main(int argc, char **argv)
                atexit(remove_pid);
        }
 
+#ifdef RESOLVE_SYMBOLS
+       load_syms(argv[0]);
+#endif
        argv = init_set_proc_title(argc, argv);
 
 #if defined(UTILITY)
diff --git a/core/util.c b/core/util.c
index a4949d6..9d446ea 100644
--- a/core/util.c
+++ b/core/util.c
@@ -34,6 +34,10 @@
 #include <time.h>
 #include <unistd.h>
 
+#ifdef RESOLVE_SYMBOLS
+#include <bfd.h>
+#endif
+
 #include <util.h>
 #include <fiber.h>
 
@@ -96,10 +100,11 @@ xrealloc(void *ptr, size_t size)
 }
 
 void *main_stack_frame;
+#if defined(__x86) || defined (__amd64) || defined(__i386)
 static void
 print_trace(FILE *f)
 {
-       void *dummy;
+       void *dummy = NULL;
        struct frame *frame;
        save_rbp(dummy);
        frame = dummy;
@@ -116,14 +121,121 @@ print_trace(FILE *f)
                frame = frame->rbp;
        }
 }
+#endif
 
 void __attribute__ ((noreturn))
     assert_fail(const char *assertion, const char *file, unsigned int line, 
const char *function)
 {
        fprintf(stderr, "%s:%i: %s: assertion %s failed.\n", file, line, 
function, assertion);
-#if CORO_ASM
+#if defined(__x86) || defined (__amd64) || defined(__i386)
        print_trace(stderr);
 #endif
        close_all_xcpt(0);
        abort();
 }
+
+#ifdef RESOLVE_SYMBOLS
+struct fsym *fsyms;
+size_t fsyms_count;
+
+int
+compare_fsym(const void *_a, const void *_b)
+{
+       const struct fsym *a = _a, *b = _b;
+       if (a->addr > b->addr)
+               return 1;
+       if (a->addr == b->addr)
+               return 0;
+       return -1;
+}
+
+void __attribute__((constructor))
+load_syms(const char *name)
+{
+       long storage_needed;
+       asymbol **symbol_table;
+       long number_of_symbols;
+       bfd *h;
+       char **matching;
+       int j;
+
+       bfd_init();
+       h = bfd_openr (name, NULL);
+       if (h == NULL)
+               goto out;
+
+       if (bfd_check_format(h, bfd_archive))
+               goto out;
+
+       if (!bfd_check_format_matches(h, bfd_object, &matching))
+               goto out;
+
+       storage_needed = bfd_get_symtab_upper_bound(h);
+
+       if (storage_needed <= 0)
+                goto out;
+
+       symbol_table = malloc(storage_needed);
+       number_of_symbols = bfd_canonicalize_symtab (h, symbol_table);
+       if (number_of_symbols < 0)
+               goto out;
+
+       for (int i = 0; i < number_of_symbols; i++)
+               if (symbol_table[i]->flags & BSF_FUNCTION &&
+                   symbol_table[i]->value > 0)
+                       fsyms_count++;
+       j = 0;
+       fsyms = malloc(fsyms_count * sizeof(struct fsym));
+
+       for (int i = 0; i < number_of_symbols; i++) {
+               struct bfd_section *section;
+               unsigned long int vma, size;
+               section = bfd_get_section(symbol_table[i]);
+               vma = bfd_get_section_vma(h, section);
+               size = bfd_get_section_size(section);
+
+               if (symbol_table[i]->flags & BSF_FUNCTION &&
+                   vma + symbol_table[i]->value > 0 &&
+                   symbol_table[i]->value < size)
+               {
+                       fsyms[j].name = strdup(symbol_table[i]->name);
+                       fsyms[j].addr = (void *)(uintptr_t)(vma + 
symbol_table[i]->value);
+                       fsyms[j].end = (void *)(uintptr_t)(vma + size);
+                       j++;
+               }
+       }
+
+       qsort(fsyms, fsyms_count, sizeof(struct fsym), compare_fsym);
+
+out:
+       if (symbol_table)
+               free(symbol_table);
+}
+
+struct fsym *
+addr2sym(void *addr)
+{
+       uint low = 0, high = fsyms_count, middle = -1;
+       struct fsym *ret, key = {.addr = addr};
+
+       while(low < high) {
+               middle = low + ((high - low) >> 1);
+               int diff = compare_fsym(fsyms + middle, &key);
+
+               if (diff < 0) {
+                       low = middle + 1;
+               } else if (diff > 0) {
+                       high = middle;
+               } else {
+                       ret = fsyms + middle;
+                       goto out;
+               }
+       }
+       ret = fsyms + middle - 1;
+out:
+       if (middle != -1 && ret->addr <= key.addr && key.addr < ret->end)
+               return ret;
+       return NULL;
+}
+
+#endif
diff --git a/include/util.h b/include/util.h
index fe10daa..8757f7a 100644
--- a/include/util.h
+++ b/include/util.h
@@ -117,20 +117,26 @@ struct frame {
        void *ret;
 };
 
-#if CORO_ASM
-#  if __amd64
-#    define save_rbp(rbp) asm("movq %%rbp, %0"::"m"(rbp))
-#  elif __i386
-#    define save_rbp(rbp) asm("movl %%ebp, %0"::"m"(rbp))
-#  else
-#  error unsupported architecture
-#  endif
-# else
-#   define save_rbp(rbp) (void)0
+#if __amd64
+#  define save_rbp(rbp) asm("movq %%rbp, %0"::"m"(rbp))
+#elif __i386
+#  define save_rbp(rbp) asm("movl %%ebp, %0"::"m"(rbp))
+#else
+#  define save_rbp(rbp) (void)0
 #endif
 
 extern void *main_stack_frame;
 
+#ifdef RESOLVE_SYMBOLS
+struct fsym {
+       void* addr;
+       const char *name;
+       void *end;
+};
+struct fsym *addr2sym(void *addr);
+void load_syms(const char *name);
+#endif
+
 #ifdef NDEBUG
 #  define assert(pred) (void)(0)
 #else

commit 93a5ba7d5c1edf690e4e97e61b8f0a44ea0de559
Author: Yuriy Vostrikov <[email protected]>
Date:   Fri Dec 10 16:41:20 2010 +0300

    [core] Fix rbp printing yet again.

diff --git a/core/fiber.c b/core/fiber.c
index 5dbb599..e3e32a4 100644
--- a/core/fiber.c
+++ b/core/fiber.c
@@ -1053,13 +1053,15 @@ fiber_info(struct tbuf *out)
                tbuf_printf(out, "    stack: %p\n", stack_top);
 
 #if CORO_ASM
+               tbuf_printf(out, "    exc: %p, frame: %p\n", ((void 
**)fiber->exc)[3], ((void **)fiber->exc)[3] + 2 * sizeof(void *));
+
                void *stack_bottom = fiber->coro.stack;
 
                struct frame *frame = fiber->rbp;
                tbuf_printf(out, "    backtrace:\n");
                while (stack_bottom < (void *)frame && (void *)frame < 
stack_top) {
-                       tbuf_printf(out, "        - { frame: %p, pc: %p }\n",
-                                   frame + 2 * sizeof(void *), frame->ret);
+                       tbuf_printf(out, "        - { rbp: %p, frame: %p, pc: 
%p }\n",
+                                   frame, (void *)frame + 2 * sizeof(void *), 
frame->ret);
                        frame = frame->rbp;
                }
 #endif

-- 
Tarantool -- an efficient key/value data store

_______________________________________________
Mailing list: https://launchpad.net/~tarantool-developers
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~tarantool-developers
More help   : https://help.launchpad.net/ListHelp

Reply via email to