diff --git a/include/execinfo.h b/include/execinfo.h index bd47b7a347..5fa5b35965 100644 --- a/include/execinfo.h +++ b/include/execinfo.h @@ -25,10 +25,16 @@ * Public Function Prototypes ****************************************************************************/ +#if defined(CONFIG_EABI_UNWINDER) + /* Store up to SIZE return address of the current program state in * ARRAY and return the exact number of values stored. */ -extern int backtrace(FAR void **buffer, int size); +extern int backtrace(FAR void **buffer, int size); +extern void dump_stack(void); +#else +# define dump_stack() +#endif #endif /* __INCLUDE_EXECINFO_H */ diff --git a/libs/libc/debug/Make.defs b/libs/libc/debug/Make.defs index 5d42e13d86..8b64610b73 100644 --- a/libs/libc/debug/Make.defs +++ b/libs/libc/debug/Make.defs @@ -20,7 +20,7 @@ ifeq ($(CONFIG_EABI_UNWINDER),y) -CSRCS += lib_backtrace.c +CSRCS += lib_backtrace.c lib_dumpstack.c endif diff --git a/libs/libc/debug/lib_dumpstack.c b/libs/libc/debug/lib_dumpstack.c new file mode 100644 index 0000000000..3984168068 --- /dev/null +++ b/libs/libc/debug/lib_dumpstack.c @@ -0,0 +1,68 @@ +/**************************************************************************** + * libs/libc/debug/lib_dumpstack.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include +#include + +#define DUMP_FORMAT "%*p" +#define DUMP_WIDTH (int)(2 * sizeof(FAR void *) + 3) + +#define DUMP_DEPTH 16 +#define DUMP_NITEM 8 +#define DUMP_LINESIZE (DUMP_NITEM * DUMP_WIDTH) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void dump_stack(void) +{ + FAR void *address[DUMP_DEPTH]; + char line[DUMP_LINESIZE]; + int ret = 0; + int size; + int i; + + size = backtrace(address, DUMP_DEPTH); + if (size <= 0) + { + return; + } + + for (i = 0; i < size; i++) + { + ret += snprintf(line + ret, sizeof(line) - ret, + DUMP_FORMAT, DUMP_WIDTH, address[i]); + if (i == size - 1 || ret % DUMP_LINESIZE == 0) + { + syslog(LOG_INFO, "[BackTrace]: %s\n", line); + ret = 0; + } + } +}