linux-generic: add stacktrace

Message ID 1466432247-31413-1-git-send-email-maxim.uvarov@linaro.org
State New
Headers show

Commit Message

Maxim Uvarov June 20, 2016, 2:17 p.m.
Add initial version for more verbose stacktrace for linux-
generic odp platform.
Usage:

export ODP_STACKTRACE_ENABLE=y

Thread 0 terminated with signal=11 (SIGSEGV)
./test/performance/odp_scheduling[0x4250b3]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x10330)[0x7f7ae5cc1330]
./test/performance/odp_scheduling[0x40a064]
./test/performance/odp_scheduling(main+0x2c1)[0x40a5dc]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0x7f7ae590df45]
./test/performance/odp_scheduling[0x408ed9]
odp_stacktrace.c:57:fault_handler():Program interrupted
Aborted

Then convert address to function symbol with add2line:

addr2line  -e ./test/performance/odp_scheduling 0x4250b3
/opt/Linaro/odp3.git/platform/linux-generic/odp_stacktrace.c:49

Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
---
 platform/linux-generic/Makefile.am                 |  1 +
 .../linux-generic/include/odp_debug_internal.h     |  2 +
 platform/linux-generic/odp_init.c                  |  3 +
 platform/linux-generic/odp_stacktrace.c            | 75 ++++++++++++++++++++++
 4 files changed, 81 insertions(+)
 create mode 100644 platform/linux-generic/odp_stacktrace.c

Comments

Maxim Uvarov Aug. 26, 2016, 3:47 p.m. | #1
ping

On 06/20/16 17:17, Maxim Uvarov wrote:
> Add initial version for more verbose stacktrace for linux-

> generic odp platform.

> Usage:

>

> export ODP_STACKTRACE_ENABLE=y

>

> Thread 0 terminated with signal=11 (SIGSEGV)

> ./test/performance/odp_scheduling[0x4250b3]

> /lib/x86_64-linux-gnu/libpthread.so.0(+0x10330)[0x7f7ae5cc1330]

> ./test/performance/odp_scheduling[0x40a064]

> ./test/performance/odp_scheduling(main+0x2c1)[0x40a5dc]

> /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0x7f7ae590df45]

> ./test/performance/odp_scheduling[0x408ed9]

> odp_stacktrace.c:57:fault_handler():Program interrupted

> Aborted

>

> Then convert address to function symbol with add2line:

>

> addr2line  -e ./test/performance/odp_scheduling 0x4250b3

> /opt/Linaro/odp3.git/platform/linux-generic/odp_stacktrace.c:49

>

> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>

> ---

>   platform/linux-generic/Makefile.am                 |  1 +

>   .../linux-generic/include/odp_debug_internal.h     |  2 +

>   platform/linux-generic/odp_init.c                  |  3 +

>   platform/linux-generic/odp_stacktrace.c            | 75 ++++++++++++++++++++++

>   4 files changed, 81 insertions(+)

>   create mode 100644 platform/linux-generic/odp_stacktrace.c

>

> diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am

> index 469869e..3598adc 100644

> --- a/platform/linux-generic/Makefile.am

> +++ b/platform/linux-generic/Makefile.am

> @@ -171,6 +171,7 @@ __LIB__libodp_linux_la_SOURCES = \

>   			   odp_spinlock.c \

>   			   odp_spinlock_recursive.c \

>   			   odp_system_info.c \

> +			   odp_stacktrace.c \

>   			   odp_thread.c \

>   			   odp_thrmask.c \

>   			   odp_ticketlock.c \

> diff --git a/platform/linux-generic/include/odp_debug_internal.h b/platform/linux-generic/include/odp_debug_internal.h

> index 02ae87a..a43705f 100644

> --- a/platform/linux-generic/include/odp_debug_internal.h

> +++ b/platform/linux-generic/include/odp_debug_internal.h

> @@ -83,6 +83,8 @@ extern "C" {

>   #define ODP_PRINT(fmt, ...) \

>   	odp_global_data.log_fn(ODP_LOG_PRINT, " " fmt, ##__VA_ARGS__)

>   

> +void _odp_stracktrace_init(void);

> +

>   #ifdef __cplusplus

>   }

>   #endif

> diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c

> index f58f410..492dd67 100644

> --- a/platform/linux-generic/odp_init.c

> +++ b/platform/linux-generic/odp_init.c

> @@ -32,6 +32,9 @@ int odp_init_global(odp_instance_t *instance,

>   			odp_global_data.abort_fn = params->abort_fn;

>   	}

>   

> +	if (getenv("ODP_STACKTRACE_ENABLE"))

> +		_odp_stracktrace_init();

> +

>   	if (odp_cpumask_init_global(params)) {

>   		ODP_ERR("ODP cpumask init failed.\n");

>   		goto init_failed;

> diff --git a/platform/linux-generic/odp_stacktrace.c b/platform/linux-generic/odp_stacktrace.c

> new file mode 100644

> index 0000000..76a8803

> --- /dev/null

> +++ b/platform/linux-generic/odp_stacktrace.c

> @@ -0,0 +1,75 @@

> +/* Copyright (c) 2016, Linaro Limited

> + * All rights reserved.

> + *

> + * SPDX-License-Identifier:     BSD-3-Clause

> + */

> +

> +#include <odp_posix_extensions.h>

> +

> +#include <odp/api/spinlock.h>

> +#include <odp_debug_internal.h>

> +

> +#include <string.h>

> +#include <stdio.h>

> +#include <signal.h>

> +#include <execinfo.h>

> +#include <unistd.h>

> +#include <sys/time.h>

> +#include <sys/resource.h>

> +

> +static odp_spinlock_t print_lock;

> +

> +static void fault_handler(int signal)

> +{

> +	size_t num_stack_frames;

> +	const char  *signal_name;

> +	void  *bt_array[4096];

> +	sigset_t sigset;

> +

> +	/* disable all signals */

> +	sigfillset(&sigset);

> +	sigprocmask(SIG_BLOCK, &sigset, NULL);

> +

> +	switch (signal) {

> +	case SIGILL:

> +		signal_name = "SIGILL";   break;

> +	case SIGFPE:

> +		signal_name = "SIGFPE";   break;

> +	case SIGSEGV:

> +		signal_name = "SIGSEGV";  break;

> +	case SIGTERM:

> +		signal_name = "SIGTERM";  break;

> +	case SIGBUS:

> +		signal_name = "SIGBUS";   break;

> +	default:

> +		signal_name = "UNKNOWN";  break;

> +	}

> +

> +	odp_spinlock_lock(&print_lock);

> +	num_stack_frames = backtrace(bt_array, 100);

> +	fprintf(stderr, "\nThread %d terminated with signal=%u (%s)\n",

> +		odp_thread_id(), signal, signal_name);

> +	backtrace_symbols_fd(bt_array, num_stack_frames, fileno(stderr));

> +	fflush(NULL);

> +	sync();

> +	odp_spinlock_unlock(&print_lock);

> +

> +	ODP_ABORT("Program interrupted\n");

> +}

> +

> +void _odp_stracktrace_init(void)

> +{

> +	struct sigaction signal_action;

> +

> +	odp_spinlock_init(&print_lock);

> +

> +	memset(&signal_action, 0, sizeof(signal_action));

> +	signal_action.sa_handler = fault_handler;

> +	sigfillset(&signal_action.sa_mask);

> +

> +	sigaction(SIGILL,  &signal_action, NULL);

> +	sigaction(SIGFPE,  &signal_action, NULL);

> +	sigaction(SIGSEGV, &signal_action, NULL);

> +	sigaction(SIGTERM, &signal_action, NULL);

> +	sigaction(SIGBUS,  &signal_action, NULL);

> +}
Mike Holmes Aug. 26, 2016, 5:43 p.m. | #2
On 20 June 2016 at 10:17, Maxim Uvarov <maxim.uvarov@linaro.org> wrote:

> Add initial version for more verbose stacktrace for linux-

> generic odp platform.

> Usage:

>

> export ODP_STACKTRACE_ENABLE=y

>

> Thread 0 terminated with signal=11 (SIGSEGV)

> ./test/performance/odp_scheduling[0x4250b3]

> /lib/x86_64-linux-gnu/libpthread.so.0(+0x10330)[0x7f7ae5cc1330]

> ./test/performance/odp_scheduling[0x40a064]

> ./test/performance/odp_scheduling(main+0x2c1)[0x40a5dc]

> /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0x7f7ae590df45]

> ./test/performance/odp_scheduling[0x408ed9]

> odp_stacktrace.c:57:fault_handler():Program interrupted

> Aborted

>

> Then convert address to function symbol with add2line:



> addr2line  -e ./test/performance/odp_scheduling 0x4250b3

> /opt/Linaro/odp3.git/platform/linux-generic/odp_stacktrace.c:49




need to mention setting ulimit -c unlimited


> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>

> ---

>  platform/linux-generic/Makefile.am                 |  1 +

>  .../linux-generic/include/odp_debug_internal.h     |  2 +

>  platform/linux-generic/odp_init.c                  |  3 +

>  platform/linux-generic/odp_stacktrace.c            | 75

> ++++++++++++++++++++++

>  4 files changed, 81 insertions(+)

>  create mode 100644 platform/linux-generic/odp_stacktrace.c

>

> diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/

> Makefile.am

> index 469869e..3598adc 100644

> --- a/platform/linux-generic/Makefile.am

> +++ b/platform/linux-generic/Makefile.am

> @@ -171,6 +171,7 @@ __LIB__libodp_linux_la_SOURCES = \

>                            odp_spinlock.c \

>                            odp_spinlock_recursive.c \

>                            odp_system_info.c \

> +                          odp_stacktrace.c \

>                            odp_thread.c \

>                            odp_thrmask.c \

>                            odp_ticketlock.c \

> diff --git a/platform/linux-generic/include/odp_debug_internal.h

> b/platform/linux-generic/include/odp_debug_internal.h

> index 02ae87a..a43705f 100644

> --- a/platform/linux-generic/include/odp_debug_internal.h

> +++ b/platform/linux-generic/include/odp_debug_internal.h

> @@ -83,6 +83,8 @@ extern "C" {

>  #define ODP_PRINT(fmt, ...) \

>         odp_global_data.log_fn(ODP_LOG_PRINT, " " fmt, ##__VA_ARGS__)

>

> +void _odp_stracktrace_init(void);

> +

>  #ifdef __cplusplus

>  }

>


Can this be part of the linux helpers so that all implementations benefit ?
The init just needs to occur in the application so we could add
odph_linux_enable_stacktrace(...)

Maybe the attachment to the actual library with ODP_ABORT is worth it, not
sure, the spin lock can be a posix one if it is outside I assume.

This does work in my simple testing and could be nice when run from CI by
updating check-odp to do so.

Mike


>  #endif

> diff --git a/platform/linux-generic/odp_init.c

> b/platform/linux-generic/odp_init.c

> index f58f410..492dd67 100644

> --- a/platform/linux-generic/odp_init.c

> +++ b/platform/linux-generic/odp_init.c

> @@ -32,6 +32,9 @@ int odp_init_global(odp_instance_t *instance,

>                         odp_global_data.abort_fn = params->abort_fn;

>         }

>

> +       if (getenv("ODP_STACKTRACE_ENABLE"))

> +               _odp_stracktrace_init();

> +

>         if (odp_cpumask_init_global(params)) {

>                 ODP_ERR("ODP cpumask init failed.\n");

>                 goto init_failed;

> diff --git a/platform/linux-generic/odp_stacktrace.c

> b/platform/linux-generic/odp_stacktrace.c

> new file mode 100644

> index 0000000..76a8803

> --- /dev/null

> +++ b/platform/linux-generic/odp_stacktrace.c

> @@ -0,0 +1,75 @@

> +/* Copyright (c) 2016, Linaro Limited

> + * All rights reserved.

> + *

> + * SPDX-License-Identifier:     BSD-3-Clause

> + */

> +

> +#include <odp_posix_extensions.h>

> +

> +#include <odp/api/spinlock.h>

> +#include <odp_debug_internal.h>

> +

> +#include <string.h>

> +#include <stdio.h>

> +#include <signal.h>

> +#include <execinfo.h>

> +#include <unistd.h>

> +#include <sys/time.h>

> +#include <sys/resource.h>

> +

> +static odp_spinlock_t print_lock;

> +

> +static void fault_handler(int signal)

> +{

> +       size_t num_stack_frames;

> +       const char  *signal_name;

> +       void  *bt_array[4096];

> +       sigset_t sigset;

> +

> +       /* disable all signals */

> +       sigfillset(&sigset);

> +       sigprocmask(SIG_BLOCK, &sigset, NULL);

> +

> +       switch (signal) {

> +       case SIGILL:

> +               signal_name = "SIGILL";   break;

> +       case SIGFPE:

> +               signal_name = "SIGFPE";   break;

> +       case SIGSEGV:

> +               signal_name = "SIGSEGV";  break;

> +       case SIGTERM:

> +               signal_name = "SIGTERM";  break;

> +       case SIGBUS:

> +               signal_name = "SIGBUS";   break;

> +       default:

> +               signal_name = "UNKNOWN";  break;

> +       }

> +

> +       odp_spinlock_lock(&print_lock);

> +       num_stack_frames = backtrace(bt_array, 100);

> +       fprintf(stderr, "\nThread %d terminated with signal=%u (%s)\n",

> +               odp_thread_id(), signal, signal_name);

> +       backtrace_symbols_fd(bt_array, num_stack_frames, fileno(stderr));

> +       fflush(NULL);

> +       sync();

> +       odp_spinlock_unlock(&print_lock);

> +

> +       ODP_ABORT("Program interrupted\n");

> +}

> +

> +void _odp_stracktrace_init(void)

> +{

> +       struct sigaction signal_action;

> +

> +       odp_spinlock_init(&print_lock);

> +

> +       memset(&signal_action, 0, sizeof(signal_action));

> +       signal_action.sa_handler = fault_handler;

> +       sigfillset(&signal_action.sa_mask);

> +

> +       sigaction(SIGILL,  &signal_action, NULL);

> +       sigaction(SIGFPE,  &signal_action, NULL);

> +       sigaction(SIGSEGV, &signal_action, NULL);

> +       sigaction(SIGTERM, &signal_action, NULL);

> +       sigaction(SIGBUS,  &signal_action, NULL);

> +}

> --

> 2.7.1.250.gff4ea60

>

> _______________________________________________

> lng-odp mailing list

> lng-odp@lists.linaro.org

> https://lists.linaro.org/mailman/listinfo/lng-odp

>




-- 
Mike Holmes
Program Manager - Linaro Networking Group
Linaro.org <http://www.linaro.org/> *│ *Open source software for ARM SoCs
"Work should be fun and collaborative, the rest follows"
Maxim Uvarov Aug. 29, 2016, 8:19 a.m. | #3
On 08/26/16 20:43, Mike Holmes wrote:
>

>

> On 20 June 2016 at 10:17, Maxim Uvarov <maxim.uvarov@linaro.org 

> <mailto:maxim.uvarov@linaro.org>> wrote:

>

>     Add initial version for more verbose stacktrace for linux-

>     generic odp platform.

>     Usage:

>

>     export ODP_STACKTRACE_ENABLE=y

>

>     Thread 0 terminated with signal=11 (SIGSEGV)

>     ./test/performance/odp_scheduling[0x4250b3]

>     /lib/x86_64-linux-gnu/libpthread.so.0(+0x10330)[0x7f7ae5cc1330]

>     ./test/performance/odp_scheduling[0x40a064]

>     ./test/performance/odp_scheduling(main+0x2c1)[0x40a5dc]

>     /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0x7f7ae590df45]

>     ./test/performance/odp_scheduling[0x408ed9]

>     odp_stacktrace.c:57:fault_handler():Program interrupted

>     Aborted

>

>     Then convert address to function symbol with add2line: 

>

>

>     addr2line  -e ./test/performance/odp_scheduling 0x4250b3

>     /opt/Linaro/odp3.git/platform/linux-generic/odp_stacktrace.c:49 

>

>

>

> need to mention setting ulimit -c unlimited

>


It does not save core dump it unrolls it in memory. Man of 
backtrace_symbols_fd()
also does not say that it needs some core limit setting. So I think it's 
not needed.

>

>     Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org

>     <mailto:maxim.uvarov@linaro.org>>

>     ---

>      platform/linux-generic/Makefile.am  |  1 +

>      .../linux-generic/include/odp_debug_internal.h  |  2 +

>      platform/linux-generic/odp_init.c |  3 +

>      platform/linux-generic/odp_stacktrace.c            | 75

>     ++++++++++++++++++++++

>      4 files changed, 81 insertions(+)

>      create mode 100644 platform/linux-generic/odp_stacktrace.c

>

>     diff --git a/platform/linux-generic/Makefile.am

>     b/platform/linux-generic/Makefile.am

>     index 469869e..3598adc 100644

>     --- a/platform/linux-generic/Makefile.am

>     +++ b/platform/linux-generic/Makefile.am

>     @@ -171,6 +171,7 @@ __LIB__libodp_linux_la_SOURCES = \

>                                odp_spinlock.c \

>                                odp_spinlock_recursive.c \

>                                odp_system_info.c \

>     +                          odp_stacktrace.c \

>                                odp_thread.c \

>                                odp_thrmask.c \

>                                odp_ticketlock.c \

>     diff --git a/platform/linux-generic/include/odp_debug_internal.h

>     b/platform/linux-generic/include/odp_debug_internal.h

>     index 02ae87a..a43705f 100644

>     --- a/platform/linux-generic/include/odp_debug_internal.h

>     +++ b/platform/linux-generic/include/odp_debug_internal.h

>     @@ -83,6 +83,8 @@ extern "C" {

>      #define ODP_PRINT(fmt, ...) \

>             odp_global_data.log_fn(ODP_LOG_PRINT, " " fmt, ##__VA_ARGS__)

>

>     +void _odp_stracktrace_init(void);

>     +

>      #ifdef __cplusplus

>      }

>

>

> Can this be part of the linux helpers so that all implementations 

> benefit ?

> The init just needs to occur in the application so we could add

> odph_linux_enable_stacktrace(...)

>

> Maybe the attachment to the actual library with ODP_ABORT is worth it, 

> not sure, the spin lock can be a posix one if it is outside I assume.

>

> This does work in my simple testing and could be nice when run from CI 

> by updating check-odp to do so.

>

> Mike


To move it to helpers sound like a good idea. Will send v2 for helpers.

Maxim.

>      #endif

>     diff --git a/platform/linux-generic/odp_init.c

>     b/platform/linux-generic/odp_init.c

>     index f58f410..492dd67 100644

>     --- a/platform/linux-generic/odp_init.c

>     +++ b/platform/linux-generic/odp_init.c

>     @@ -32,6 +32,9 @@ int odp_init_global(odp_instance_t *instance,

>                             odp_global_data.abort_fn = params->abort_fn;

>             }

>

>     +       if (getenv("ODP_STACKTRACE_ENABLE"))

>     +               _odp_stracktrace_init();

>     +

>             if (odp_cpumask_init_global(params)) {

>                     ODP_ERR("ODP cpumask init failed.\n");

>                     goto init_failed;

>     diff --git a/platform/linux-generic/odp_stacktrace.c

>     b/platform/linux-generic/odp_stacktrace.c

>     new file mode 100644

>     index 0000000..76a8803

>     --- /dev/null

>     +++ b/platform/linux-generic/odp_stacktrace.c

>     @@ -0,0 +1,75 @@

>     +/* Copyright (c) 2016, Linaro Limited

>     + * All rights reserved.

>     + *

>     + * SPDX-License-Identifier:     BSD-3-Clause

>     + */

>     +

>     +#include <odp_posix_extensions.h>

>     +

>     +#include <odp/api/spinlock.h>

>     +#include <odp_debug_internal.h>

>     +

>     +#include <string.h>

>     +#include <stdio.h>

>     +#include <signal.h>

>     +#include <execinfo.h>

>     +#include <unistd.h>

>     +#include <sys/time.h>

>     +#include <sys/resource.h>

>     +

>     +static odp_spinlock_t print_lock;

>     +

>     +static void fault_handler(int signal)

>     +{

>     +       size_t num_stack_frames;

>     +       const char  *signal_name;

>     +       void  *bt_array[4096];

>     +       sigset_t sigset;

>     +

>     +       /* disable all signals */

>     +       sigfillset(&sigset);

>     +       sigprocmask(SIG_BLOCK, &sigset, NULL);

>     +

>     +       switch (signal) {

>     +       case SIGILL:

>     +               signal_name = "SIGILL";   break;

>     +       case SIGFPE:

>     +               signal_name = "SIGFPE";   break;

>     +       case SIGSEGV:

>     +               signal_name = "SIGSEGV";  break;

>     +       case SIGTERM:

>     +               signal_name = "SIGTERM";  break;

>     +       case SIGBUS:

>     +               signal_name = "SIGBUS";   break;

>     +       default:

>     +               signal_name = "UNKNOWN";  break;

>     +       }

>     +

>     +       odp_spinlock_lock(&print_lock);

>     +       num_stack_frames = backtrace(bt_array, 100);

>     +       fprintf(stderr, "\nThread %d terminated with signal=%u

>     (%s)\n",

>     +               odp_thread_id(), signal, signal_name);

>     +       backtrace_symbols_fd(bt_array, num_stack_frames,

>     fileno(stderr));

>     +       fflush(NULL);

>     +       sync();

>     +       odp_spinlock_unlock(&print_lock);

>     +

>     +       ODP_ABORT("Program interrupted\n");

>     +}

>     +

>     +void _odp_stracktrace_init(void)

>     +{

>     +       struct sigaction signal_action;

>     +

>     +       odp_spinlock_init(&print_lock);

>     +

>     +       memset(&signal_action, 0, sizeof(signal_action));

>     +       signal_action.sa_handler = fault_handler;

>     +       sigfillset(&signal_action.sa_mask);

>     +

>     +       sigaction(SIGILL,  &signal_action, NULL);

>     +       sigaction(SIGFPE,  &signal_action, NULL);

>     +       sigaction(SIGSEGV, &signal_action, NULL);

>     +       sigaction(SIGTERM, &signal_action, NULL);

>     +       sigaction(SIGBUS,  &signal_action, NULL);

>     +}

>     --

>     2.7.1.250.gff4ea60

>

>     _______________________________________________

>     lng-odp mailing list

>     lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org>

>     https://lists.linaro.org/mailman/listinfo/lng-odp

>     <https://lists.linaro.org/mailman/listinfo/lng-odp>

>

>

>

>

> -- 

> Mike Holmes

> Program Manager - Linaro Networking Group

> Linaro.org <http://www.linaro.org/>***│ *Open source software for ARM SoCs

> "Work should be fun and collaborative, the rest follows"

>
Mike Holmes Aug. 29, 2016, 12:21 p.m. | #4
On 29 August 2016 at 04:19, Maxim Uvarov <maxim.uvarov@linaro.org> wrote:

> On 08/26/16 20:43, Mike Holmes wrote:

>

>>

>>

>> On 20 June 2016 at 10:17, Maxim Uvarov <maxim.uvarov@linaro.org <mailto:

>> maxim.uvarov@linaro.org>> wrote:

>>

>>     Add initial version for more verbose stacktrace for linux-

>>     generic odp platform.

>>     Usage:

>>

>>     export ODP_STACKTRACE_ENABLE=y

>>

>>     Thread 0 terminated with signal=11 (SIGSEGV)

>>     ./test/performance/odp_scheduling[0x4250b3]

>>     /lib/x86_64-linux-gnu/libpthread.so.0(+0x10330)[0x7f7ae5cc1330]

>>     ./test/performance/odp_scheduling[0x40a064]

>>     ./test/performance/odp_scheduling(main+0x2c1)[0x40a5dc]

>>     /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf5)[0x7f

>> 7ae590df45]

>>     ./test/performance/odp_scheduling[0x408ed9]

>>     odp_stacktrace.c:57:fault_handler():Program interrupted

>>     Aborted

>>

>>     Then convert address to function symbol with add2line:

>>

>>     addr2line  -e ./test/performance/odp_scheduling 0x4250b3

>>     /opt/Linaro/odp3.git/platform/linux-generic/odp_stacktrace.c:49

>>

>>

>> need to mention setting ulimit -c unlimited

>>

>>

> It does not save core dump it unrolls it in memory. Man of

> backtrace_symbols_fd()

> also does not say that it needs some core limit setting. So I think it's

> not needed.

>

>

>>     Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org

>>     <mailto:maxim.uvarov@linaro.org>>

>>

>>     ---

>>      platform/linux-generic/Makefile.am  |  1 +

>>      .../linux-generic/include/odp_debug_internal.h  |  2 +

>>      platform/linux-generic/odp_init.c |  3 +

>>      platform/linux-generic/odp_stacktrace.c            | 75

>>     ++++++++++++++++++++++

>>      4 files changed, 81 insertions(+)

>>      create mode 100644 platform/linux-generic/odp_stacktrace.c

>>

>>     diff --git a/platform/linux-generic/Makefile.am

>>     b/platform/linux-generic/Makefile.am

>>     index 469869e..3598adc 100644

>>     --- a/platform/linux-generic/Makefile.am

>>     +++ b/platform/linux-generic/Makefile.am

>>     @@ -171,6 +171,7 @@ __LIB__libodp_linux_la_SOURCES = \

>>                                odp_spinlock.c \

>>                                odp_spinlock_recursive.c \

>>                                odp_system_info.c \

>>     +                          odp_stacktrace.c \

>>                                odp_thread.c \

>>                                odp_thrmask.c \

>>                                odp_ticketlock.c \

>>     diff --git a/platform/linux-generic/include/odp_debug_internal.h

>>     b/platform/linux-generic/include/odp_debug_internal.h

>>     index 02ae87a..a43705f 100644

>>     --- a/platform/linux-generic/include/odp_debug_internal.h

>>     +++ b/platform/linux-generic/include/odp_debug_internal.h

>>     @@ -83,6 +83,8 @@ extern "C" {

>>      #define ODP_PRINT(fmt, ...) \

>>             odp_global_data.log_fn(ODP_LOG_PRINT, " " fmt, ##__VA_ARGS__)

>>

>>     +void _odp_stracktrace_init(void);

>>     +

>>      #ifdef __cplusplus

>>      }

>>

>>

>> Can this be part of the linux helpers so that all implementations benefit

>> ?

>> The init just needs to occur in the application so we could add

>> odph_linux_enable_stacktrace(...)

>>

>> Maybe the attachment to the actual library with ODP_ABORT is worth it,

>> not sure, the spin lock can be a posix one if it is outside I assume.

>>

>> This does work in my simple testing and could be nice when run from CI by

>> updating check-odp to do so.

>>

>> Mike

>>

>

> To move it to helpers sound like a good idea. Will send v2 for helpers.

>


If that sounds good to you maybe we pick a non linux specific API name vs
my first suggestion, that way other OSes are free to implement the same
functionality if they can, if not they can just return with no harm.


> Maxim.

>

>      #endif

>>     diff --git a/platform/linux-generic/odp_init.c

>>     b/platform/linux-generic/odp_init.c

>>     index f58f410..492dd67 100644

>>     --- a/platform/linux-generic/odp_init.c

>>     +++ b/platform/linux-generic/odp_init.c

>>     @@ -32,6 +32,9 @@ int odp_init_global(odp_instance_t *instance,

>>                             odp_global_data.abort_fn = params->abort_fn;

>>             }

>>

>>     +       if (getenv("ODP_STACKTRACE_ENABLE"))

>>     +               _odp_stracktrace_init();

>>     +

>>             if (odp_cpumask_init_global(params)) {

>>                     ODP_ERR("ODP cpumask init failed.\n");

>>                     goto init_failed;

>>     diff --git a/platform/linux-generic/odp_stacktrace.c

>>     b/platform/linux-generic/odp_stacktrace.c

>>     new file mode 100644

>>     index 0000000..76a8803

>>     --- /dev/null

>>     +++ b/platform/linux-generic/odp_stacktrace.c

>>     @@ -0,0 +1,75 @@

>>     +/* Copyright (c) 2016, Linaro Limited

>>     + * All rights reserved.

>>     + *

>>     + * SPDX-License-Identifier:     BSD-3-Clause

>>     + */

>>     +

>>     +#include <odp_posix_extensions.h>

>>     +

>>     +#include <odp/api/spinlock.h>

>>     +#include <odp_debug_internal.h>

>>     +

>>     +#include <string.h>

>>     +#include <stdio.h>

>>     +#include <signal.h>

>>     +#include <execinfo.h>

>>     +#include <unistd.h>

>>     +#include <sys/time.h>

>>     +#include <sys/resource.h>

>>     +

>>     +static odp_spinlock_t print_lock;

>>     +

>>     +static void fault_handler(int signal)

>>     +{

>>     +       size_t num_stack_frames;

>>     +       const char  *signal_name;

>>     +       void  *bt_array[4096];

>>     +       sigset_t sigset;

>>     +

>>     +       /* disable all signals */

>>     +       sigfillset(&sigset);

>>     +       sigprocmask(SIG_BLOCK, &sigset, NULL);

>>     +

>>     +       switch (signal) {

>>     +       case SIGILL:

>>     +               signal_name = "SIGILL";   break;

>>     +       case SIGFPE:

>>     +               signal_name = "SIGFPE";   break;

>>     +       case SIGSEGV:

>>     +               signal_name = "SIGSEGV";  break;

>>     +       case SIGTERM:

>>     +               signal_name = "SIGTERM";  break;

>>     +       case SIGBUS:

>>     +               signal_name = "SIGBUS";   break;

>>     +       default:

>>     +               signal_name = "UNKNOWN";  break;

>>     +       }

>>     +

>>     +       odp_spinlock_lock(&print_lock);

>>     +       num_stack_frames = backtrace(bt_array, 100);

>>     +       fprintf(stderr, "\nThread %d terminated with signal=%u

>>     (%s)\n",

>>     +               odp_thread_id(), signal, signal_name);

>>     +       backtrace_symbols_fd(bt_array, num_stack_frames,

>>     fileno(stderr));

>>     +       fflush(NULL);

>>     +       sync();

>>     +       odp_spinlock_unlock(&print_lock);

>>     +

>>     +       ODP_ABORT("Program interrupted\n");

>>     +}

>>     +

>>     +void _odp_stracktrace_init(void)

>>     +{

>>     +       struct sigaction signal_action;

>>     +

>>     +       odp_spinlock_init(&print_lock);

>>     +

>>     +       memset(&signal_action, 0, sizeof(signal_action));

>>     +       signal_action.sa_handler = fault_handler;

>>     +       sigfillset(&signal_action.sa_mask);

>>     +

>>     +       sigaction(SIGILL,  &signal_action, NULL);

>>     +       sigaction(SIGFPE,  &signal_action, NULL);

>>     +       sigaction(SIGSEGV, &signal_action, NULL);

>>     +       sigaction(SIGTERM, &signal_action, NULL);

>>     +       sigaction(SIGBUS,  &signal_action, NULL);

>>     +}

>>     --

>>     2.7.1.250.gff4ea60

>>

>>     _______________________________________________

>>     lng-odp mailing list

>>     lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org>

>>     https://lists.linaro.org/mailman/listinfo/lng-odp

>>     <https://lists.linaro.org/mailman/listinfo/lng-odp>

>>

>>

>>

>>

>> --

>> Mike Holmes

>> Program Manager - Linaro Networking Group

>> Linaro.org <http://www.linaro.org/>***│ *Open source software for ARM

>> SoCs

>> "Work should be fun and collaborative, the rest follows"

>>

>>

>



-- 
Mike Holmes
Program Manager - Linaro Networking Group
Linaro.org <http://www.linaro.org/> *│ *Open source software for ARM SoCs
"Work should be fun and collaborative, the rest follows"

Patch

diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index 469869e..3598adc 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -171,6 +171,7 @@  __LIB__libodp_linux_la_SOURCES = \
 			   odp_spinlock.c \
 			   odp_spinlock_recursive.c \
 			   odp_system_info.c \
+			   odp_stacktrace.c \
 			   odp_thread.c \
 			   odp_thrmask.c \
 			   odp_ticketlock.c \
diff --git a/platform/linux-generic/include/odp_debug_internal.h b/platform/linux-generic/include/odp_debug_internal.h
index 02ae87a..a43705f 100644
--- a/platform/linux-generic/include/odp_debug_internal.h
+++ b/platform/linux-generic/include/odp_debug_internal.h
@@ -83,6 +83,8 @@  extern "C" {
 #define ODP_PRINT(fmt, ...) \
 	odp_global_data.log_fn(ODP_LOG_PRINT, " " fmt, ##__VA_ARGS__)
 
+void _odp_stracktrace_init(void);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/platform/linux-generic/odp_init.c b/platform/linux-generic/odp_init.c
index f58f410..492dd67 100644
--- a/platform/linux-generic/odp_init.c
+++ b/platform/linux-generic/odp_init.c
@@ -32,6 +32,9 @@  int odp_init_global(odp_instance_t *instance,
 			odp_global_data.abort_fn = params->abort_fn;
 	}
 
+	if (getenv("ODP_STACKTRACE_ENABLE"))
+		_odp_stracktrace_init();
+
 	if (odp_cpumask_init_global(params)) {
 		ODP_ERR("ODP cpumask init failed.\n");
 		goto init_failed;
diff --git a/platform/linux-generic/odp_stacktrace.c b/platform/linux-generic/odp_stacktrace.c
new file mode 100644
index 0000000..76a8803
--- /dev/null
+++ b/platform/linux-generic/odp_stacktrace.c
@@ -0,0 +1,75 @@ 
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#include <odp_posix_extensions.h>
+
+#include <odp/api/spinlock.h>
+#include <odp_debug_internal.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <signal.h>
+#include <execinfo.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+static odp_spinlock_t print_lock;
+
+static void fault_handler(int signal)
+{
+	size_t num_stack_frames;
+	const char  *signal_name;
+	void  *bt_array[4096];
+	sigset_t sigset;
+
+	/* disable all signals */
+	sigfillset(&sigset);
+	sigprocmask(SIG_BLOCK, &sigset, NULL);
+
+	switch (signal) {
+	case SIGILL:
+		signal_name = "SIGILL";   break;
+	case SIGFPE:
+		signal_name = "SIGFPE";   break;
+	case SIGSEGV:
+		signal_name = "SIGSEGV";  break;
+	case SIGTERM:
+		signal_name = "SIGTERM";  break;
+	case SIGBUS:
+		signal_name = "SIGBUS";   break;
+	default:
+		signal_name = "UNKNOWN";  break;
+	}
+
+	odp_spinlock_lock(&print_lock);
+	num_stack_frames = backtrace(bt_array, 100);
+	fprintf(stderr, "\nThread %d terminated with signal=%u (%s)\n",
+		odp_thread_id(), signal, signal_name);
+	backtrace_symbols_fd(bt_array, num_stack_frames, fileno(stderr));
+	fflush(NULL);
+	sync();
+	odp_spinlock_unlock(&print_lock);
+
+	ODP_ABORT("Program interrupted\n");
+}
+
+void _odp_stracktrace_init(void)
+{
+	struct sigaction signal_action;
+
+	odp_spinlock_init(&print_lock);
+
+	memset(&signal_action, 0, sizeof(signal_action));
+	signal_action.sa_handler = fault_handler;
+	sigfillset(&signal_action.sa_mask);
+
+	sigaction(SIGILL,  &signal_action, NULL);
+	sigaction(SIGFPE,  &signal_action, NULL);
+	sigaction(SIGSEGV, &signal_action, NULL);
+	sigaction(SIGTERM, &signal_action, NULL);
+	sigaction(SIGBUS,  &signal_action, NULL);
+}