summaryrefslogtreecommitdiffstats
path: root/vespamalloc/src/tests/stacktrace
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /vespamalloc/src/tests/stacktrace
Publish
Diffstat (limited to 'vespamalloc/src/tests/stacktrace')
-rw-r--r--vespamalloc/src/tests/stacktrace/.gitignore3
-rw-r--r--vespamalloc/src/tests/stacktrace/CMakeLists.txt12
-rw-r--r--vespamalloc/src/tests/stacktrace/DESC1
-rw-r--r--vespamalloc/src/tests/stacktrace/FILES1
-rw-r--r--vespamalloc/src/tests/stacktrace/backtrace.c84
-rw-r--r--vespamalloc/src/tests/stacktrace/backtrace.h17
-rw-r--r--vespamalloc/src/tests/stacktrace/stacktrace.cpp35
7 files changed, 153 insertions, 0 deletions
diff --git a/vespamalloc/src/tests/stacktrace/.gitignore b/vespamalloc/src/tests/stacktrace/.gitignore
new file mode 100644
index 00000000000..669d726db1e
--- /dev/null
+++ b/vespamalloc/src/tests/stacktrace/.gitignore
@@ -0,0 +1,3 @@
+*_test*
+.depend
+Makefile
diff --git a/vespamalloc/src/tests/stacktrace/CMakeLists.txt b/vespamalloc/src/tests/stacktrace/CMakeLists.txt
new file mode 100644
index 00000000000..6d8fbfcbaa1
--- /dev/null
+++ b/vespamalloc/src/tests/stacktrace/CMakeLists.txt
@@ -0,0 +1,12 @@
+# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+vespa_add_executable(vespamalloc_stacktrace_test_app
+ SOURCES
+ stacktrace.cpp
+ backtrace.c
+ DEPENDS
+)
+vespa_add_test(
+ NAME vespamalloc_stacktrace_test_app
+ NO_VALGRIND COMMAND vespamalloc_stacktrace_test_app
+ ENVIRONMENT "LD_PRELOAD=${CMAKE_CURRENT_BINARY_DIR}/../../vespamalloc/libvespamalloc_vespamallocdst16.so"
+ NO_VALGRIND)
diff --git a/vespamalloc/src/tests/stacktrace/DESC b/vespamalloc/src/tests/stacktrace/DESC
new file mode 100644
index 00000000000..5f30c916321
--- /dev/null
+++ b/vespamalloc/src/tests/stacktrace/DESC
@@ -0,0 +1 @@
+Test that the stacktrace functionality works as expected.
diff --git a/vespamalloc/src/tests/stacktrace/FILES b/vespamalloc/src/tests/stacktrace/FILES
new file mode 100644
index 00000000000..24b43aa0f89
--- /dev/null
+++ b/vespamalloc/src/tests/stacktrace/FILES
@@ -0,0 +1 @@
+stacktrace.cpp
diff --git a/vespamalloc/src/tests/stacktrace/backtrace.c b/vespamalloc/src/tests/stacktrace/backtrace.c
new file mode 100644
index 00000000000..d594caa3368
--- /dev/null
+++ b/vespamalloc/src/tests/stacktrace/backtrace.c
@@ -0,0 +1,84 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include "backtrace.h"
+
+#if defined(__i386__)
+// use GLIBC version, hope it works
+extern int backtrace(void **buffer, int size);
+#define HAVE_BACKTRACE
+#endif
+
+#if defined(__x86_64__)
+
+/**
+ Written by Arne H. J. based on docs:
+
+ http://www.kernel.org/pub/linux/devel/gcc/unwind/
+ http://www.codesourcery.com/public/cxx-abi/abi-eh.html
+ http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/libgcc-s-ddefs.html
+**/
+
+#include <unwind.h>
+
+struct trace_context {
+ void **array;
+ int size;
+ int index;
+};
+
+static _Unwind_Reason_Code
+trace_fn(struct _Unwind_Context *ctxt, void *arg)
+{
+ struct trace_context *tp = (struct trace_context *)arg;
+ void *ip = (void *)_Unwind_GetIP(ctxt);
+
+ if (ip == 0) {
+ return _URC_END_OF_STACK;
+ }
+ if (tp->index <= tp->size) {
+ // there's no point filling in the address of the backtrace()
+ // function itself, that doesn't provide any extra information,
+ // so skip one level
+ if (tp->index > 0) {
+ tp->array[tp->index - 1] = ip;
+ }
+ tp->index++;
+ } else {
+ return _URC_NORMAL_STOP;
+ }
+ return _URC_NO_REASON; // "This is not the destination frame" -> try next frame
+}
+
+#define HAVE_BACKTRACE
+int
+backtrace (void **array, int size)
+{
+ struct trace_context t;
+ t.array = array;
+ t.size = size;
+ t.index = 0;
+ _Unwind_Backtrace(trace_fn, &t);
+ return t.index - 1;
+}
+#endif // x86_64
+
+
+#ifdef HAVE_BACKTRACE
+
+int
+FastOS_backtrace (void **array, int size)
+{
+ return backtrace(array, size);
+}
+
+#else
+
+# warning "backtrace not supported on this CPU"
+int
+FastOS_backtrace (void **array, int size)
+{
+ (void) array;
+ (void) size;
+ return 0;
+}
+
+#endif
diff --git a/vespamalloc/src/tests/stacktrace/backtrace.h b/vespamalloc/src/tests/stacktrace/backtrace.h
new file mode 100644
index 00000000000..45c1ef1378d
--- /dev/null
+++ b/vespamalloc/src/tests/stacktrace/backtrace.h
@@ -0,0 +1,17 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int FastOS_backtrace (void **array, int size);
+
+#if defined(__x86_64__)
+int backtrace (void **array, int size);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/vespamalloc/src/tests/stacktrace/stacktrace.cpp b/vespamalloc/src/tests/stacktrace/stacktrace.cpp
new file mode 100644
index 00000000000..0fb0c9759a2
--- /dev/null
+++ b/vespamalloc/src/tests/stacktrace/stacktrace.cpp
@@ -0,0 +1,35 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+
+void * run(void * arg)
+{
+ (void) arg;
+ char * a = new char [100]; // a should not remain in stacktrace
+ char * b = new char [1]; // but b should as it not deleted.
+ (void) b;
+ delete [] a;
+ return NULL;
+}
+
+int main(int argc, char *argv[])
+{
+ (void) argc;
+ (void) argv;
+ char * a = new char [100]; // a should not remain in stacktrace
+ char * b = new char [1]; // but b should as it not deleted.
+ (void) b;
+ delete [] a;
+ pthread_t tid;
+ int retval = pthread_create(&tid, NULL, run, NULL);
+ if (retval != 0) {
+ perror("pthread_create failed");
+ abort();
+ }
+ retval = pthread_join(tid, NULL);
+ if (retval != 0) {
+ perror("pthread_join failed");
+ abort();
+ }
+}