[PATCH] common: add printf debugging automation
Jules Maselbas
jmaselbas at kalray.eu
Sun Mar 6 14:49:01 PST 2022
Hi Ahmad,
On Sat, Mar 05, 2022 at 11:20:13PM +0100, Ahmad Fatoum wrote:
> This allows automating pinpointing of breakage outside PBL. For example
> if barebox is stuck during startup:
>
> - Turn on CONFIG_DEBUG_LL and CONFIG_DEBUG_INITCALLS
> - Note last $initcall executed
By $initcall are you talking about the function name or about the
initcall address during startup ?
> - Set CONFIG_FTRACE_CALLCHAIN=$initcall
> - Serial output will stop at the last called traced function
>
> Alternatively, enable CONFIG_FTRACE and stick tracing_on() somewhere.
>
> Output will look like:
>
> [<4fd859a5>] (netconsole_init+0x1/0x120) from [<4fd014c7>] (start_barebox+0x43/0x7c)
> [<4fd77209>] (xzalloc+0x1/0x34) from [<4fd859bd>] (netconsole_init+0x19/0x120)
> [<4fd7719d>] (xmalloc+0x1/0x34) from [<4fd77221>] (xzalloc+0x19/0x34)
> [<4fd0995d>] (malloc+0x1/0x54) from [<4fd771b5>] (xmalloc+0x19/0x34)
> [<4fd0aae1>] (tlsf_malloc+0x1/0x48) from [<4fd09983>] (malloc+0x27/0x54)
> [<4fd0a1d9>] (adjust_request_size+0x1/0x44) from [<4fd0aaff>] (tlsf_malloc+0x1f/0x48)
> [<4fd0a18d>] (align_up+0x1/0x4c) from [<4fd0a205>] (adjust_request_size+0x2d/0x44)
> [<4fd0aa55>] (block_locate_free+0x1/0x8c) from [<4fd0ab09>] (tlsf_malloc+0x29/0x48)
>
> This is added as an experimental feature as it's not meant to be enabled
> at all time due to large overhead and may change considerably in future,
> e.g. to allow dumping to memory buffer and to record timestamps for
> profiling.
>
> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> ---
> Makefile | 10 +++++-
> common/Kconfig | 15 +++++++++
> include/ftrace.h | 18 +++++++++++
> lib/Makefile | 4 +++
> lib/ftrace.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++
> lib/kasan/Makefile | 5 +++
> 6 files changed, 128 insertions(+), 1 deletion(-)
> create mode 100644 include/ftrace.h
> create mode 100644 lib/ftrace.c
>
> diff --git a/Makefile b/Makefile
> index c04deaaa0f69..34743f4b6b45 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -469,7 +469,7 @@ export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
> export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE
> export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
> export LDFLAGS_barebox
> -export LDFLAGS_pbl
> +export LDFLAGS_pbl PBL_CPPFLAGS
>
> export CFLAGS_UBSAN
> export CFLAGS_KASAN CFLAGS_KASAN_NOSANITIZE
> @@ -682,6 +682,14 @@ KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,)
> # change __FILE__ to the relative path from the srctree
> KBUILD_CFLAGS += $(call cc-option,-fmacro-prefix-map=$(srctree)/=)
>
> +# The arch Makefiles can override CC_FLAGS_FTRACE. We may also append it later.
> +ifdef CONFIG_FTRACE
> +CC_FLAGS_FTRACE := -finstrument-functions
> +export CC_FLAGS_FTRACE
> +KBUILD_CFLAGS += $(CC_FLAGS_FTRACE)
> +PBL_CPPFLAGS += -fno-instrument-functions
> +endif
> +
> include-y +=scripts/Makefile.ubsan
> include-$(CONFIG_KASAN) += scripts/Makefile.kasan
>
> diff --git a/common/Kconfig b/common/Kconfig
> index b8c3e34c0a58..2a35b43e2717 100644
> --- a/common/Kconfig
> +++ b/common/Kconfig
> @@ -1592,6 +1592,21 @@ config ASAN
> Enables ASAN (AddressSANitizer) - runtime memory debugger,
> designed to find out-of-bounds accesses and use-after-free bugs.
>
> +config FTRACE
> + bool "Enable function tracing (Only for debugging!)
missing closing quote here --------------------------------^
which generated the following warning when building:
common/Kconfig:1583:warning: multi-line strings not supported
> + depends on EXPERIMENTAL
> + help
> + This is not Linux-like ftrace, but a poor man's substitute using
> + GCC function instrumentation.
> +
> +config FTRACE_CALLCHAIN
> + string "Print execution trace of all function below"
> + depends on FTRACE && KALLSYMS
> + default ""
> + help
> + All functions called directly or indirectly by the specified
> + function will be logged to serial. Keep empty to disable
> +
> config COMPILE_TEST
> bool "compile-test drivers of other platforms"
> default n
> diff --git a/include/ftrace.h b/include/ftrace.h
> new file mode 100644
> index 000000000000..68b46f1fa1d4
> --- /dev/null
> +++ b/include/ftrace.h
> @@ -0,0 +1,18 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#ifndef _FTRACE_H__
> +#define _FTRACE_H__
> +
> +#ifdef CONFIG_FTRACE
> +void tracing_on(void);
> +void tracing_off(void);
> +#else
> +static inline void tracing_on(void)
> +{
> +}
> +static inline void tracing_off(void)
> +{
> +}
> +#endif
> +
> +#endif /* _FTRACE_H */
> diff --git a/lib/Makefile b/lib/Makefile
> index 3f6653d74e9a..7b86ad3383c3 100644
> --- a/lib/Makefile
> +++ b/lib/Makefile
> @@ -73,6 +73,7 @@ obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o
> obj-$(CONFIG_CRC8) += crc8.o
> obj-$(CONFIG_NLS) += nls_base.o
> obj-$(CONFIG_FSL_QE_FIRMWARE) += fsl-qe-firmware.o
> +obj-$(CONFIG_FTRACE) += ftrace.o
> obj-$(CONFIG_UBSAN) += ubsan.o
>
> # GCC library routines
> @@ -85,6 +86,9 @@ pbl-$(CONFIG_GENERIC_LIB_ASHLDI3) += ashldi3.o
>
> UBSAN_SANITIZE_ubsan.o := n
>
> +CFLAGS_REMOVE_ubsan.o = $(CC_FLAGS_FTRACE)
> +CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE)
> +
> libfdt_files = fdt.o fdt_ro.o fdt_wip.o fdt_rw.o fdt_sw.o fdt_strerror.o \
> fdt_empty_tree.o
> $(foreach file, $(libfdt_files), \
> diff --git a/lib/ftrace.c b/lib/ftrace.c
> new file mode 100644
> index 000000000000..1d0b36c10550
> --- /dev/null
> +++ b/lib/ftrace.c
> @@ -0,0 +1,77 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +
> +#include <common.h>
> +#include <clock.h>
> +#include <ftrace.h>
> +#include <kallsyms.h>
> +
> +static int trace_enabled __section(".data");
> +static volatile int trace_lock __section(".data");
> +static int depth __section(".data");
> +static const void *trigger __section(".data");
> +
> +void notrace tracing_on(void)
> +{
> + if (trace_lock)
> + return;
> + trigger = NULL;
> + trace_enabled = 1;
> +}
> +
> +void notrace tracing_off(void)
> +{
> + if (trace_lock)
> + return;
> + trigger = NULL;
> + trace_enabled = 0;
> +}
> +
> +void notrace __cyg_profile_func_enter(void *where, void *from)
> +{
> + if (trace_lock)
> + return;
> +
> + if (trace_enabled <= 0) {
> + if (where == trigger)
> + trace_enabled++;
> + else
> + return;
> + }
> +
> + depth++;
> +
> + trace_lock = true;
> +
> + printf(" [<%08lx>] %*s(%pS) from [<%08lx>] (%pS)\n", (ulong) where,
> + depth * 2, "", where, (ulong)from, from);
> +
> + trace_lock = false;
> +}
> +
> +void notrace __cyg_profile_func_exit(void *where, void *from)
> +{
> + if (trace_lock || !trace_enabled)
> + return;
> +
> + depth--;
> +
> + if (where == trigger)
> + trace_enabled--;
> +}
> +
> +static int init_trace(void)
> +{
> + ulong _trigger;
> +
> + trace_lock = true;
> +
> + _trigger = kallsyms_lookup_name(CONFIG_FTRACE_CALLCHAIN);
> + if (IS_ENABLED(CONFIG_THUMB2_BAREBOX))
> + _trigger |= 1;
> + trigger = (void *)_trigger;
> +
> + trace_lock = false;
> +
> + return 0;
> +}
> +pure_initcall(init_trace);
> diff --git a/lib/kasan/Makefile b/lib/kasan/Makefile
> index e3f4bb61f900..06fa906ff620 100644
> --- a/lib/kasan/Makefile
> +++ b/lib/kasan/Makefile
> @@ -13,3 +13,8 @@ CFLAGS_generic_report.o := $(CC_FLAGS_KASAN_RUNTIME)
> CFLAGS_generic.o := $(CC_FLAGS_KASAN_RUNTIME)
> CFLAGS_report.o := $(CC_FLAGS_KASAN_RUNTIME)
> CFLAGS_common.o := $(CC_FLAGS_KASAN_RUNTIME)
> +
> +CFLAGS_REMOVE_generic_report.o = $(CC_FLAGS_FTRACE)
> +CFLAGS_REMOVE_generic.o = $(CC_FLAGS_FTRACE)
> +CFLAGS_REMOVE_report.o = $(CC_FLAGS_FTRACE)
> +CFLAGS_REMOVE_common.o = $(CC_FLAGS_FTRACE)
> --
> 2.30.2
More information about the barebox
mailing list