diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
commit | 72231250ed81e10d66bfe70701e64fa5fe50f712 (patch) | |
tree | 2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /vespamalloc/src/tests/stacktrace |
Publish
Diffstat (limited to 'vespamalloc/src/tests/stacktrace')
-rw-r--r-- | vespamalloc/src/tests/stacktrace/.gitignore | 3 | ||||
-rw-r--r-- | vespamalloc/src/tests/stacktrace/CMakeLists.txt | 12 | ||||
-rw-r--r-- | vespamalloc/src/tests/stacktrace/DESC | 1 | ||||
-rw-r--r-- | vespamalloc/src/tests/stacktrace/FILES | 1 | ||||
-rw-r--r-- | vespamalloc/src/tests/stacktrace/backtrace.c | 84 | ||||
-rw-r--r-- | vespamalloc/src/tests/stacktrace/backtrace.h | 17 | ||||
-rw-r--r-- | vespamalloc/src/tests/stacktrace/stacktrace.cpp | 35 |
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(); + } +} |