From 49c510429c234419003a66fef0d6f0e96a1e0559 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Wed, 22 Jun 2022 15:55:14 +0300 Subject: [PATCH 01/34] Add package "stack-trace" --- ChangeLog | 1 + Makefile.am | 3 +++ README.md | 3 ++- configure.ac | 6 ++++++ include/Makefile.am | 3 +++ include/kernaux.h.in | 1 + include/kernaux/stack_trace.h | 12 ++++++++++++ src/stack_trace.c | 5 +++++ 8 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 include/kernaux/stack_trace.h create mode 100644 src/stack_trace.c diff --git a/ChangeLog b/ChangeLog index 6851f7d1..cb2ba9fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,7 @@ 2022-06-22 Alex Kotov * include/kernaux/free_list.h: Finished + * include/kernaux/stack_trace.h: Added 2022-06-21 Alex Kotov diff --git a/Makefile.am b/Makefile.am index b1e38983..427752e4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -89,6 +89,9 @@ endif if WITH_PRINTF_FMT libkernaux_la_SOURCES += src/printf_fmt.c endif +if WITH_STACK_TRACE +libkernaux_la_SOURCES += src/stack_trace.c +endif if WITH_UNITS libkernaux_la_SOURCES += src/units.c endif diff --git a/README.md b/README.md index 38e66974..ac4efb78 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ zero). Work-in-progress APIs can change at any time. * [Assertions](/include/kernaux/assert.h) (*non-breaking since* **0.4.0**) * [Example: Assert](/examples/assert.c) * [Example: Panic](/examples/panic.c) - * Stack trace *(planned)* + * [Stack trace](/include/kernaux/stack_trace.h) *(work in progress)* * [Input/output](/include/kernaux/io.h) (*work in progress*) * Architecture-specific code (*work in progress*) * [Declarations](/include/kernaux/arch/) @@ -160,6 +160,7 @@ explicitly included, use `--without-all`. * `--with[out]-memmap` - memory map * `--with[out]-ntoa` - itoa/ftoa * `--with[out]-printf` - printf +* `--with[out]-stack-trace` - stack trace diff --git a/configure.ac b/configure.ac index 1095946b..67b9a685 100644 --- a/configure.ac +++ b/configure.ac @@ -70,6 +70,7 @@ AC_ARG_WITH( [ntoa], AS_HELP_STRING([--without-ntoa], [without i AC_ARG_WITH( [pfa], AS_HELP_STRING([--without-pfa], [without Page Frame Allocator])) AC_ARG_WITH( [printf], AS_HELP_STRING([--without-printf], [without printf])) AC_ARG_WITH( [printf-fmt], AS_HELP_STRING([--without-printf-fmt], [without printf format parser])) +AC_ARG_WITH( [stack-trace], AS_HELP_STRING([--without-stack-trace], [without stack trace])) AC_ARG_WITH( [units], AS_HELP_STRING([--without-units], [without measurement units utils])) dnl Packages (disabled by default) @@ -103,6 +104,7 @@ if test -z "$with_ntoa"; then with_ntoa=no; fi if test -z "$with_pfa"; then with_pfa=no; fi if test -z "$with_printf"; then with_printf=no; fi if test -z "$with_printf_fmt"; then with_printf_fmt=no; fi +if test -z "$with_stack_trace"; then with_stack_trace=no; fi if test -z "$with_units"; then with_units=no; fi ]) AS_IF([test "$with_all" = no], do_without_all) @@ -140,6 +142,7 @@ AS_IF([test "$with_ntoa" = no ], [with_ntoa=no], [with_ntoa AS_IF([test "$with_pfa" = no ], [with_pfa=no], [with_pfa=yes]) AS_IF([test "$with_printf" = no ], [with_printf=no], [with_printf=yes]) AS_IF([test "$with_printf_fmt" = no ], [with_printf_fmt=no], [with_printf_fmt=yes]) +AS_IF([test "$with_stack_trace" = no ], [with_stack_trace=no], [with_stack_trace=yes]) AS_IF([test "$with_units" = no ], [with_units=no], [with_units=yes]) dnl Packages (disabled by default) @@ -196,6 +199,7 @@ AM_CONDITIONAL([WITH_NTOA], [test "$with_ntoa" = yes]) AM_CONDITIONAL([WITH_PFA], [test "$with_pfa" = yes]) AM_CONDITIONAL([WITH_PRINTF], [test "$with_printf" = yes]) AM_CONDITIONAL([WITH_PRINTF_FMT], [test "$with_printf_fmt" = yes]) +AM_CONDITIONAL([WITH_STACK_TRACE], [test "$with_stack_trace" = yes]) AM_CONDITIONAL([WITH_UNITS], [test "$with_units" = yes]) dnl Packages (disabled by default) @@ -237,6 +241,7 @@ AS_IF([test "$with_ntoa" = yes], [AC_DEFINE([WITH_NTOA], [1] AS_IF([test "$with_pfa" = yes], [AC_DEFINE([WITH_PFA], [1], [with Page Frame Allocator])]) AS_IF([test "$with_printf" = yes], [AC_DEFINE([WITH_PRINTF], [1], [with printf])]) AS_IF([test "$with_printf_fmt" = yes], [AC_DEFINE([WITH_PRINTF_FMT], [1], [with printf format parser])]) +AS_IF([test "$with_stack_trace" = yes], [AC_DEFINE([WITH_STACK_TRACE], [1], [with stack trace])]) AS_IF([test "$with_units", = yes], [AC_DEFINE([WITH_UNITS], [1], [with measurement units utils])]) dnl Packages (disabled by default) @@ -265,6 +270,7 @@ AS_IF([test "$with_ntoa" = no], [AC_SUBST([comment_line_ntoa], [// AS_IF([test "$with_pfa" = no], [AC_SUBST([comment_line_pfa], [//])]) AS_IF([test "$with_printf" = no], [AC_SUBST([comment_line_printf], [//])]) AS_IF([test "$with_printf_fmt" = no], [AC_SUBST([comment_line_printf_fmt], [//])]) +AS_IF([test "$with_stack_trace" = no], [AC_SUBST([comment_line_stack_trace], [//])]) AS_IF([test "$with_units" = no], [AC_SUBST([comment_line_units], [//])]) diff --git a/include/Makefile.am b/include/Makefile.am index 45e9ce02..f864a09c 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -58,6 +58,9 @@ endif if WITH_PRINTF_FMT nobase_include_HEADERS += kernaux/printf_fmt.h endif +if WITH_STACK_TRACE +nobase_include_HEADERS += kernaux/stack_trace.h +endif if WITH_UNITS nobase_include_HEADERS += kernaux/units.h endif diff --git a/include/kernaux.h.in b/include/kernaux.h.in index 92c339ce..7c8a3c1a 100644 --- a/include/kernaux.h.in +++ b/include/kernaux.h.in @@ -23,6 +23,7 @@ @comment_line_pfa@#include @comment_line_printf@#include @comment_line_printf_fmt@#include +@comment_line_stack_trace@#include @comment_line_units@#include #include diff --git a/include/kernaux/stack_trace.h b/include/kernaux/stack_trace.h new file mode 100644 index 00000000..6a124de9 --- /dev/null +++ b/include/kernaux/stack_trace.h @@ -0,0 +1,12 @@ +#ifndef KERNAUX_INCLUDED_STACK_TRACE +#define KERNAUX_INCLUDED_STACK_TRACE + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/stack_trace.c b/src/stack_trace.c new file mode 100644 index 00000000..448f6e93 --- /dev/null +++ b/src/stack_trace.c @@ -0,0 +1,5 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include From dc07e1dc81e02a431c3879ebaddfef11ccc74315 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Wed, 22 Jun 2022 16:00:04 +0300 Subject: [PATCH 02/34] Add function "kernaux_stack_trace_snprint" --- include/kernaux/stack_trace.h | 4 ++++ src/stack_trace.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/include/kernaux/stack_trace.h b/include/kernaux/stack_trace.h index 6a124de9..ba75ff29 100644 --- a/include/kernaux/stack_trace.h +++ b/include/kernaux/stack_trace.h @@ -5,6 +5,10 @@ extern "C" { #endif +#include + +void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size); + #ifdef __cplusplus } #endif diff --git a/src/stack_trace.c b/src/stack_trace.c index 448f6e93..3129b399 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -3,3 +3,7 @@ #endif #include + +void kernaux_stack_trace_snprint(char *const buffer, const size_t buffer_size) +{ +} From a9c427ad5e4de0b2f6175f9979f89949c88d9e20 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Wed, 22 Jun 2022 16:03:53 +0300 Subject: [PATCH 03/34] Add copyrights --- COPYING | 1 + src/stack_trace.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/COPYING b/COPYING index 3adbc015..5b12c83a 100644 --- a/COPYING +++ b/COPYING @@ -6,6 +6,7 @@ Copyright (c) 2011 Nicholas J. Kain Copyright (c) 2011-2015 Rich Felker Copyright (c) 2014-2019 Marco Paland Copyright (c) 2017-2022 Embedded Artistry LLC +Copyright (c) 2022-2022 mintsuki Copyright (c) 2022 Alexander Monakov Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/src/stack_trace.c b/src/stack_trace.c index 3129b399..c170dd34 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -1,3 +1,10 @@ +/** + * The code was inspired by the Limine bootloader. + * + * Copyright (c) 2020-2022 mintsuki + * Copyright (c) 2022 Alex Kotov + */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif From d1d73007daaa4c59fbdacaaa961369a077e41bbd Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Wed, 22 Jun 2022 16:05:21 +0300 Subject: [PATCH 04/34] Add assertions --- src/stack_trace.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/stack_trace.c b/src/stack_trace.c index c170dd34..f63f819c 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -9,8 +9,11 @@ #include "config.h" #endif +#include #include void kernaux_stack_trace_snprint(char *const buffer, const size_t buffer_size) { + KERNAUX_ASSERT(buffer); + KERNAUX_ASSERT(buffer_size > 0); } From 5e53c46bf1aa8c1bb098f3af6b40de4f112c05d3 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Wed, 22 Jun 2022 16:13:07 +0300 Subject: [PATCH 05/34] Get ptr --- src/stack_trace.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/stack_trace.c b/src/stack_trace.c index f63f819c..1f83d806 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -12,8 +12,26 @@ #include #include +#include + void kernaux_stack_trace_snprint(char *const buffer, const size_t buffer_size) { KERNAUX_ASSERT(buffer); KERNAUX_ASSERT(buffer_size > 0); + +#if !defined(ASM_I386) && !defined(ASM_X86_64) + (void)buffer_size; // unused + buffer[0] = '\0'; // empty string +#else + size_t *ptr = NULL; + __asm__ volatile( +#if defined(ASM_I386) + "movl %%ebp, %0" +#elif defined(ASM_X86_64) + "movq %%rbp, %0" +#endif + : "=g"(ptr) + :: "memory" + ); +#endif // !defined(ASM_I386) && !defined(ASM_X86_64) } From dc8265f89db4cc083ceec100526ab265513ed427 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Wed, 22 Jun 2022 16:24:33 +0300 Subject: [PATCH 06/34] Implement stack trace loop --- src/stack_trace.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/stack_trace.c b/src/stack_trace.c index 1f83d806..c7f3a304 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -14,6 +14,8 @@ #include +static const char *trace(size_t *offset, size_t ret_addr); + void kernaux_stack_trace_snprint(char *const buffer, const size_t buffer_size) { KERNAUX_ASSERT(buffer); @@ -33,5 +35,27 @@ void kernaux_stack_trace_snprint(char *const buffer, const size_t buffer_size) : "=g"(ptr) :: "memory" ); + + for (;;) { + size_t old_bp = ptr[0]; + size_t ret_addr = ptr[1]; + if (!ret_addr) break; + + size_t offset = 0; + const char *const name = trace(&offset, ret_addr); + if (name) { + } else { + } + + if (!old_bp) break; + ptr = (void*)old_bp; + } #endif // !defined(ASM_I386) && !defined(ASM_X86_64) } + +static const char *trace(size_t *const offset, const size_t ret_addr) +{ + *offset = 0; + (void)ret_addr; + return NULL; +} From 8bb757f2b72c2b5f0bfee60f5d732d923390fc48 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Wed, 22 Jun 2022 16:31:41 +0300 Subject: [PATCH 07/34] Print stack trace --- configure.ac | 7 ++++--- src/stack_trace.c | 22 +++++++++++++++++++++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 67b9a685..a31af6c6 100644 --- a/configure.ac +++ b/configure.ac @@ -159,9 +159,10 @@ AS_IF([test "$enable_tests_python" = yes -a "$enable_freestanding" = yes], AC_MS AS_IF([test "$enable_tests" = yes -a "$with_libc" = yes], AC_MSG_ERROR([can not use package `libc' with tests])) AS_IF([test "$enable_tests_python" = yes -a "$with_libc" = yes], AC_MSG_ERROR([can not use package `libc' with tests])) -AS_IF([test "$with_printf" = yes -a "$with_ntoa" = no], AC_MSG_ERROR([package `printf' requires package `ntoa'])) -AS_IF([test "$with_printf" = yes -a "$with_printf_fmt" = no], AC_MSG_ERROR([package `printf' requires package `printf-fmt'])) -AS_IF([test "$with_units" = yes -a "$with_ntoa" = no], AC_MSG_ERROR([package `units' requires package `ntoa'])) +AS_IF([test "$with_printf" = yes -a "$with_ntoa" = no], AC_MSG_ERROR([package `printf' requires package `ntoa'])) +AS_IF([test "$with_printf" = yes -a "$with_printf_fmt" = no], AC_MSG_ERROR([package `printf' requires package `printf-fmt'])) +AS_IF([test "$with_stack_trace" = yes -a "$with_printf" = no], AC_MSG_ERROR([package `stack-trace' requires package `printf'])) +AS_IF([test "$with_units" = yes -a "$with_ntoa" = no], AC_MSG_ERROR([package `units' requires package `ntoa'])) diff --git a/src/stack_trace.c b/src/stack_trace.c index c7f3a304..460299e4 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -10,13 +10,14 @@ #endif #include +#include #include #include static const char *trace(size_t *offset, size_t ret_addr); -void kernaux_stack_trace_snprint(char *const buffer, const size_t buffer_size) +void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size) { KERNAUX_ASSERT(buffer); KERNAUX_ASSERT(buffer_size > 0); @@ -43,8 +44,27 @@ void kernaux_stack_trace_snprint(char *const buffer, const size_t buffer_size) size_t offset = 0; const char *const name = trace(&offset, ret_addr); + int snprintf_result; if (name) { + snprintf_result = kernaux_snprintf( + buffer, + buffer_size, + "[%p] <%s + %p>\n", + ret_addr, + name, + offset + ); } else { + snprintf_result = kernaux_snprintf( + buffer, + buffer_size, + "[%p]\n", + ret_addr + ); + } + if (snprintf_result > 0 && (size_t)snprintf_result < buffer_size) { + buffer_size -= snprintf_result; + buffer += snprintf_result; } if (!old_bp) break; From 50722522a492698fd01d9ba97ce8a7a6adc2e7fb Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Wed, 22 Jun 2022 16:32:24 +0300 Subject: [PATCH 08/34] Example values --- src/stack_trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stack_trace.c b/src/stack_trace.c index 460299e4..26298a31 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -75,7 +75,7 @@ void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size) static const char *trace(size_t *const offset, const size_t ret_addr) { - *offset = 0; + *offset = 0xa8; // example (void)ret_addr; - return NULL; + return "foobar"; // example } From 6dfc257f0fe0accaab889bc945f252a8b05fc576 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Wed, 22 Jun 2022 16:36:31 +0300 Subject: [PATCH 09/34] Add "tests/test_stack_trace" --- .gitignore | 1 + tests/Makefile.am | 12 +++++++++++ tests/test_stack_trace.c | 45 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 tests/test_stack_trace.c diff --git a/.gitignore b/.gitignore index 668b2ef2..236f0d82 100644 --- a/.gitignore +++ b/.gitignore @@ -148,4 +148,5 @@ /tests/test_printf_gen /tests/test_printf_gen.c /tests/test_printf_reg +/tests/test_stack_trace /tests/test_units_human diff --git a/tests/Makefile.am b/tests/Makefile.am index d5d476e8..dcaa349c 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -347,6 +347,18 @@ test_printf_reg_SOURCES = \ test_printf_reg.c endif +#################### +# test_stack_trace # +#################### + +if WITH_STACK_TRACE +TESTS += test_stack_trace +test_stack_trace_LDADD = $(top_builddir)/libkernaux.la +test_stack_trace_SOURCES = \ + main.c \ + test_stack_trace.c +endif + #################### # test_units_human # #################### diff --git a/tests/test_stack_trace.c b/tests/test_stack_trace.c new file mode 100644 index 00000000..295668be --- /dev/null +++ b/tests/test_stack_trace.c @@ -0,0 +1,45 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +#include + +static void func1(); +static void func2(); +static void func3(); +static void func4(); +static void func5(); + +void test_main() +{ + func1(); +} + +void func1() +{ + func2(); +} + +void func2() +{ + func3(); +} + +void func3() +{ + func4(); +} + +void func4() +{ + func5(); +} + +void func5() +{ + char buffer[1000]; + kernaux_stack_trace_snprint(buffer, sizeof(buffer)); + printf("%s", buffer); +} From 8008290664ae999e91ac38ebe8a0f43e6ed073ef Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Wed, 22 Jun 2022 16:38:05 +0300 Subject: [PATCH 10/34] Better output --- src/stack_trace.c | 8 +++++--- tests/test_stack_trace.c | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/stack_trace.c b/src/stack_trace.c index 26298a31..53d950d3 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -37,7 +37,7 @@ void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size) :: "memory" ); - for (;;) { + for (size_t index = 0;; ++index) { size_t old_bp = ptr[0]; size_t ret_addr = ptr[1]; if (!ret_addr) break; @@ -49,7 +49,8 @@ void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size) snprintf_result = kernaux_snprintf( buffer, buffer_size, - "[%p] <%s + %p>\n", + "%lu: 0x%p: %s + 0x%p\n", + index, ret_addr, name, offset @@ -58,7 +59,8 @@ void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size) snprintf_result = kernaux_snprintf( buffer, buffer_size, - "[%p]\n", + "%lu: 0x%p\n", + index, ret_addr ); } diff --git a/tests/test_stack_trace.c b/tests/test_stack_trace.c index 295668be..6b72143c 100644 --- a/tests/test_stack_trace.c +++ b/tests/test_stack_trace.c @@ -41,5 +41,5 @@ void func5() { char buffer[1000]; kernaux_stack_trace_snprint(buffer, sizeof(buffer)); - printf("%s", buffer); + printf("Stack trace:\n%s", buffer); } From 39668512207e5f0a95701ae0d0e19f56019d8e4d Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Wed, 22 Jun 2022 17:06:06 +0300 Subject: [PATCH 11/34] Remove symbol names --- src/stack_trace.c | 39 ++++++++------------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/src/stack_trace.c b/src/stack_trace.c index 53d950d3..292116af 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -15,8 +15,6 @@ #include -static const char *trace(size_t *offset, size_t ret_addr); - void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size) { KERNAUX_ASSERT(buffer); @@ -42,28 +40,14 @@ void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size) size_t ret_addr = ptr[1]; if (!ret_addr) break; - size_t offset = 0; - const char *const name = trace(&offset, ret_addr); - int snprintf_result; - if (name) { - snprintf_result = kernaux_snprintf( - buffer, - buffer_size, - "%lu: 0x%p: %s + 0x%p\n", - index, - ret_addr, - name, - offset - ); - } else { - snprintf_result = kernaux_snprintf( - buffer, - buffer_size, - "%lu: 0x%p\n", - index, - ret_addr - ); - } + int snprintf_result = kernaux_snprintf( + buffer, + buffer_size, + "%lu: 0x%p\n", + index, + ret_addr + ); + if (snprintf_result > 0 && (size_t)snprintf_result < buffer_size) { buffer_size -= snprintf_result; buffer += snprintf_result; @@ -74,10 +58,3 @@ void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size) } #endif // !defined(ASM_I386) && !defined(ASM_X86_64) } - -static const char *trace(size_t *const offset, const size_t ret_addr) -{ - *offset = 0xa8; // example - (void)ret_addr; - return "foobar"; // example -} From 87fe9ea7c4ad2b7079520afcd4afab287c08644b Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Tue, 29 Nov 2022 21:30:19 +0400 Subject: [PATCH 12/34] Use macro "KERNAUX_ASM" --- src/stack_trace.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/stack_trace.c b/src/stack_trace.c index 292116af..10c31be9 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -10,6 +10,7 @@ #endif #include +#include #include #include @@ -25,15 +26,11 @@ void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size) buffer[0] = '\0'; // empty string #else size_t *ptr = NULL; - __asm__ volatile( #if defined(ASM_I386) - "movl %%ebp, %0" + KERNAUX_ASM("movl %%ebp, %0" : "=g"(ptr) :: "memory"); #elif defined(ASM_X86_64) - "movq %%rbp, %0" + KERNAUX_ASM("movq %%rbp, %0" : "=g"(ptr) :: "memory"); #endif - : "=g"(ptr) - :: "memory" - ); for (size_t index = 0;; ++index) { size_t old_bp = ptr[0]; From da6795ca8a316386719fd0098f490c42a54bc61e Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Tue, 29 Nov 2022 21:33:46 +0400 Subject: [PATCH 13/34] Improve code --- src/stack_trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/stack_trace.c b/src/stack_trace.c index 10c31be9..4c9a878b 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -21,7 +21,7 @@ void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size) KERNAUX_ASSERT(buffer); KERNAUX_ASSERT(buffer_size > 0); -#if !defined(ASM_I386) && !defined(ASM_X86_64) +#ifndef ASM_X86 (void)buffer_size; // unused buffer[0] = '\0'; // empty string #else @@ -53,5 +53,5 @@ void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size) if (!old_bp) break; ptr = (void*)old_bp; } -#endif // !defined(ASM_I386) && !defined(ASM_X86_64) +#endif // ASM_X86 } From bbd4442ddcdc3adde051e134ab4e2c6286cf5417 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Tue, 29 Nov 2022 21:36:25 +0400 Subject: [PATCH 14/34] Add empty line --- src/stack_trace.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/stack_trace.c b/src/stack_trace.c index 4c9a878b..16a5507d 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -26,6 +26,7 @@ void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size) buffer[0] = '\0'; // empty string #else size_t *ptr = NULL; + #if defined(ASM_I386) KERNAUX_ASM("movl %%ebp, %0" : "=g"(ptr) :: "memory"); #elif defined(ASM_X86_64) From 33adf6dbcffbd7c11df29547ada67efec8636d54 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Tue, 29 Nov 2022 21:38:00 +0400 Subject: [PATCH 15/34] Improve code --- src/stack_trace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/stack_trace.c b/src/stack_trace.c index 16a5507d..4cfd4f92 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -21,10 +21,7 @@ void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size) KERNAUX_ASSERT(buffer); KERNAUX_ASSERT(buffer_size > 0); -#ifndef ASM_X86 - (void)buffer_size; // unused - buffer[0] = '\0'; // empty string -#else +#ifdef ASM_X86 size_t *ptr = NULL; #if defined(ASM_I386) @@ -54,5 +51,8 @@ void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size) if (!old_bp) break; ptr = (void*)old_bp; } +#else + (void)buffer_size; // unused + buffer[0] = '\0'; // empty string #endif // ASM_X86 } From f1aa3699c5e0405d02b6d37530cc0f0af63abb23 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Tue, 29 Nov 2022 21:42:08 +0400 Subject: [PATCH 16/34] Improve code --- src/stack_trace.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/stack_trace.c b/src/stack_trace.c index 4cfd4f92..589d2776 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -16,12 +16,26 @@ #include -void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size) +#ifdef ASM_X86 +static void snprint_x86(char *buffer, size_t buffer_size); +#endif + +void kernaux_stack_trace_snprint(char *const buffer, const size_t buffer_size) { KERNAUX_ASSERT(buffer); KERNAUX_ASSERT(buffer_size > 0); #ifdef ASM_X86 + snprint_x86(buffer, buffer_size); +#else + (void)buffer_size; // unused + buffer[0] = '\0'; // empty string +#endif +} + +#ifdef ASM_X86 +void snprint_x86(char *buffer, size_t buffer_size) +{ size_t *ptr = NULL; #if defined(ASM_I386) @@ -51,8 +65,5 @@ void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size) if (!old_bp) break; ptr = (void*)old_bp; } -#else - (void)buffer_size; // unused - buffer[0] = '\0'; // empty string -#endif // ASM_X86 } +#endif From 80eef3bbef789312d43a8a55922255870d172c5c Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sat, 3 Dec 2022 23:37:07 +0400 Subject: [PATCH 17/34] Rewrite API --- configure.ac | 1 - include/kernaux/stack_trace.h | 15 ++++++- src/stack_trace.c | 75 +++++++++++++++++------------------ 3 files changed, 51 insertions(+), 40 deletions(-) diff --git a/configure.ac b/configure.ac index 64534e4d..3f3a837e 100644 --- a/configure.ac +++ b/configure.ac @@ -177,7 +177,6 @@ AS_IF([test "$enable_checks_python" = yes -a "$with_libc" = yes], AC_M AS_IF([test "$with_printf" = yes -a "$with_ntoa" = no], AC_MSG_ERROR([package `printf' requires package `ntoa'])) AS_IF([test "$with_printf" = yes -a "$with_printf_fmt" = no], AC_MSG_ERROR([package `printf' requires package `printf-fmt'])) -AS_IF([test "$with_stack_trace" = yes -a "$with_printf" = no], AC_MSG_ERROR([package `stack-trace' requires package `printf'])) AS_IF([test "$with_units" = yes -a "$with_ntoa" = no], AC_MSG_ERROR([package `units' requires package `ntoa'])) diff --git a/include/kernaux/stack_trace.h b/include/kernaux/stack_trace.h index ba75ff29..54e1f162 100644 --- a/include/kernaux/stack_trace.h +++ b/include/kernaux/stack_trace.h @@ -5,9 +5,22 @@ extern "C" { #endif +#include + +#include #include +#include + +typedef struct KernAux_StackTrace_Frame { + const void *KERNAUX_PRIVATE_FIELD(ptr); +} *KernAux_StackTrace_Frame; + +struct KernAux_StackTrace_Frame KernAux_StackTrace_Frame_create(); + +bool KernAux_StackTrace_Frame_has_more(KernAux_StackTrace_Frame frame); +void KernAux_StackTrace_Frame_use_next(KernAux_StackTrace_Frame frame); -void kernaux_stack_trace_snprint(char *buffer, size_t buffer_size); +const void *KernAux_StackTrace_Frame_get_ptr(KernAux_StackTrace_Frame frame); #ifdef __cplusplus } diff --git a/src/stack_trace.c b/src/stack_trace.c index 589d2776..5a1cf92d 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -11,59 +11,58 @@ #include #include -#include #include +#include #include +#include -#ifdef ASM_X86 -static void snprint_x86(char *buffer, size_t buffer_size); +struct KernAux_StackTrace_Frame KernAux_StackTrace_Frame_create() +{ + struct KernAux_StackTrace_Frame frame; + +#if defined(ASM_I386) + KERNAUX_ASM("movl %%ebp, %0" : "=g"((const size_t*)frame.ptr) :: "memory"); +#elif defined(ASM_X86_64) + KERNAUX_ASM("movq %%rbp, %0" : "=g"((const size_t*)frame.ptr) :: "memory"); #endif -void kernaux_stack_trace_snprint(char *const buffer, const size_t buffer_size) + return frame; +} + +bool KernAux_StackTrace_Frame_has_more(const KernAux_StackTrace_Frame frame) { - KERNAUX_ASSERT(buffer); - KERNAUX_ASSERT(buffer_size > 0); + KERNAUX_ASSERT(frame); -#ifdef ASM_X86 - snprint_x86(buffer, buffer_size); +#if defined(ASM_X86) + const size_t *const ptr = frame->ptr; + return ptr[1]; #else - (void)buffer_size; // unused - buffer[0] = '\0'; // empty string + return false; #endif } -#ifdef ASM_X86 -void snprint_x86(char *buffer, size_t buffer_size) +void KernAux_StackTrace_Frame_use_next(const KernAux_StackTrace_Frame frame) { - size_t *ptr = NULL; + KERNAUX_ASSERT(frame); -#if defined(ASM_I386) - KERNAUX_ASM("movl %%ebp, %0" : "=g"(ptr) :: "memory"); -#elif defined(ASM_X86_64) - KERNAUX_ASM("movq %%rbp, %0" : "=g"(ptr) :: "memory"); -#endif - - for (size_t index = 0;; ++index) { - size_t old_bp = ptr[0]; - size_t ret_addr = ptr[1]; - if (!ret_addr) break; + if (!frame->ptr) return; - int snprintf_result = kernaux_snprintf( - buffer, - buffer_size, - "%lu: 0x%p\n", - index, - ret_addr - ); +#if defined(ASM_X86) + const size_t *const ptr = frame->ptr; + frame->ptr = (const void*)ptr[0]; +#endif +} - if (snprintf_result > 0 && (size_t)snprintf_result < buffer_size) { - buffer_size -= snprintf_result; - buffer += snprintf_result; - } +const void *KernAux_StackTrace_Frame_get_ptr( + const KernAux_StackTrace_Frame frame +) { + KERNAUX_ASSERT(frame); - if (!old_bp) break; - ptr = (void*)old_bp; - } -} +#if defined(ASM_X86) + const size_t *const ptr = frame->ptr; + return (const void*)ptr[1]; +#else + return NULL; #endif +} From 40e4df8ff655d99d720ea9a5ef3bdbc3afacb052 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sat, 3 Dec 2022 23:37:49 +0400 Subject: [PATCH 18/34] Remove old test --- tests/test_stack_trace.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/tests/test_stack_trace.c b/tests/test_stack_trace.c index 6b72143c..ad638478 100644 --- a/tests/test_stack_trace.c +++ b/tests/test_stack_trace.c @@ -4,42 +4,6 @@ #include -#include - -static void func1(); -static void func2(); -static void func3(); -static void func4(); -static void func5(); - void test_main() { - func1(); -} - -void func1() -{ - func2(); -} - -void func2() -{ - func3(); -} - -void func3() -{ - func4(); -} - -void func4() -{ - func5(); -} - -void func5() -{ - char buffer[1000]; - kernaux_stack_trace_snprint(buffer, sizeof(buffer)); - printf("Stack trace:\n%s", buffer); } From afb456e8e8a3cdc09e13c8777a61fabb7b69101d Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sat, 3 Dec 2022 23:38:34 +0400 Subject: [PATCH 19/34] Fix cppcheck --- src/stack_trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stack_trace.c b/src/stack_trace.c index 5a1cf92d..5e591288 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -19,7 +19,7 @@ struct KernAux_StackTrace_Frame KernAux_StackTrace_Frame_create() { - struct KernAux_StackTrace_Frame frame; + struct KernAux_StackTrace_Frame frame = { .ptr = NULL }; #if defined(ASM_I386) KERNAUX_ASM("movl %%ebp, %0" : "=g"((const size_t*)frame.ptr) :: "memory"); From 5f8f7405db187279579a5b78a2c1becc9cbc62c3 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sat, 3 Dec 2022 23:51:18 +0400 Subject: [PATCH 20/34] Write test --- tests/test_stack_trace.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/test_stack_trace.c b/tests/test_stack_trace.c index ad638478..f5753aa8 100644 --- a/tests/test_stack_trace.c +++ b/tests/test_stack_trace.c @@ -4,6 +4,42 @@ #include +#include +#include + +#define MIN_SIZE 20 +#define MAX_SIZE (MIN_SIZE + 5) + +static size_t min_count = 0; +static const void *min_addresses[MIN_SIZE]; + +static size_t max_count = 0; +static const void *max_addresses[MAX_SIZE]; + +#define PREPARE(lower, upper) \ + do { \ + lower##_count = 0; \ + memset(lower##_addresses, 0, sizeof(lower##_addresses)); \ +\ + for ( \ + struct KernAux_StackTrace_Frame frame = \ + KernAux_StackTrace_Frame_create(); \ + KernAux_StackTrace_Frame_has_more(&frame); \ + KernAux_StackTrace_Frame_use_next(&frame) \ + ) { \ + assert(lower##_count < upper##_SIZE - 1); \ + lower##_addresses[lower##_count++] = \ + KernAux_StackTrace_Frame_get_ptr(&frame); \ + } \ + } while (0) + void test_main() { + PREPARE(min, MIN); + + PREPARE(max, MAX); + assert(max_count == min_count); + for (size_t index = 0; index < max_count; ++index) { + assert(max_addresses[index] == min_addresses[index]); + } } From c0a145948af60b86e1ef604c9100d50dab5915f4 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sat, 3 Dec 2022 23:52:03 +0400 Subject: [PATCH 21/34] Fix error --- src/stack_trace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/stack_trace.c b/src/stack_trace.c index 5e591288..bebbd7f4 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -34,6 +34,8 @@ bool KernAux_StackTrace_Frame_has_more(const KernAux_StackTrace_Frame frame) { KERNAUX_ASSERT(frame); + if (!frame->ptr) return false; + #if defined(ASM_X86) const size_t *const ptr = frame->ptr; return ptr[1]; From a4837154c17762523650186827eb417b06432947 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sat, 3 Dec 2022 23:57:00 +0400 Subject: [PATCH 22/34] Debug output --- tests/test_stack_trace.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/test_stack_trace.c b/tests/test_stack_trace.c index f5753aa8..a10611bf 100644 --- a/tests/test_stack_trace.c +++ b/tests/test_stack_trace.c @@ -5,6 +5,7 @@ #include #include +#include #include #define MIN_SIZE 20 @@ -27,10 +28,15 @@ static const void *max_addresses[MAX_SIZE]; KernAux_StackTrace_Frame_has_more(&frame); \ KernAux_StackTrace_Frame_use_next(&frame) \ ) { \ - assert(lower##_count < upper##_SIZE - 1); \ - lower##_addresses[lower##_count++] = \ + assert(lower##_count < upper##_SIZE); \ + lower##_addresses[lower##_count] = \ KernAux_StackTrace_Frame_get_ptr(&frame); \ + printf("%lu: 0x%p\n", \ + lower##_count, lower##_addresses[lower##_count]); \ + ++lower##_count; \ } \ +\ + putchar('\n'); \ } while (0) void test_main() From 534a442b4a0700ac3dbcaca252a05bbb35df9835 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sun, 4 Dec 2022 00:08:12 +0400 Subject: [PATCH 23/34] Debug output --- tests/test_stack_trace.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_stack_trace.c b/tests/test_stack_trace.c index a10611bf..52338867 100644 --- a/tests/test_stack_trace.c +++ b/tests/test_stack_trace.c @@ -41,6 +41,14 @@ static const void *max_addresses[MAX_SIZE]; void test_main() { + int main(); + printf("main: %p\n", + (const void*)(uintptr_t)main); + printf("test_main: %p\n", + (const void*)(uintptr_t)test_main); + printf("KernAux_StackTrace_Frame_create: %p\n\n", + (const void*)(uintptr_t)KernAux_StackTrace_Frame_create); + PREPARE(min, MIN); PREPARE(max, MAX); From 5257cd19b67301524fcb819c754b19c628f2b327 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sun, 4 Dec 2022 00:39:06 +0400 Subject: [PATCH 24/34] Fix test --- tests/test_stack_trace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_stack_trace.c b/tests/test_stack_trace.c index 52338867..757d3d57 100644 --- a/tests/test_stack_trace.c +++ b/tests/test_stack_trace.c @@ -53,7 +53,7 @@ void test_main() PREPARE(max, MAX); assert(max_count == min_count); - for (size_t index = 0; index < max_count; ++index) { + for (size_t index = 1; index < max_count; ++index) { assert(max_addresses[index] == min_addresses[index]); } } From 6a7941eeaff5bb6d83fec87d57b3a0c30e48a3d4 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sun, 4 Dec 2022 00:41:30 +0400 Subject: [PATCH 25/34] Debug output --- tests/test_stack_trace.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/test_stack_trace.c b/tests/test_stack_trace.c index 757d3d57..82ff4a31 100644 --- a/tests/test_stack_trace.c +++ b/tests/test_stack_trace.c @@ -17,8 +17,10 @@ static const void *min_addresses[MIN_SIZE]; static size_t max_count = 0; static const void *max_addresses[MAX_SIZE]; -#define PREPARE(lower, upper) \ +#define PREPARE(descr, lower, upper) \ do { \ + printf("%s:\n", (descr)); \ +\ lower##_count = 0; \ memset(lower##_addresses, 0, sizeof(lower##_addresses)); \ \ @@ -31,7 +33,7 @@ static const void *max_addresses[MAX_SIZE]; assert(lower##_count < upper##_SIZE); \ lower##_addresses[lower##_count] = \ KernAux_StackTrace_Frame_get_ptr(&frame); \ - printf("%lu: 0x%p\n", \ + printf(" %lu: 0x%p\n", \ lower##_count, lower##_addresses[lower##_count]); \ ++lower##_count; \ } \ @@ -49,9 +51,9 @@ void test_main() printf("KernAux_StackTrace_Frame_create: %p\n\n", (const void*)(uintptr_t)KernAux_StackTrace_Frame_create); - PREPARE(min, MIN); + PREPARE("test_main (initial)", min, MIN); - PREPARE(max, MAX); + PREPARE("test_main (compare)", max, MAX); assert(max_count == min_count); for (size_t index = 1; index < max_count; ++index) { assert(max_addresses[index] == min_addresses[index]); From d1f2dce3f03bba4579e7cbd0987ddf48a71a870c Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sun, 4 Dec 2022 00:42:03 +0400 Subject: [PATCH 26/34] Remove unnecessary debug output --- tests/test_stack_trace.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/test_stack_trace.c b/tests/test_stack_trace.c index 82ff4a31..43383bbb 100644 --- a/tests/test_stack_trace.c +++ b/tests/test_stack_trace.c @@ -43,14 +43,6 @@ static const void *max_addresses[MAX_SIZE]; void test_main() { - int main(); - printf("main: %p\n", - (const void*)(uintptr_t)main); - printf("test_main: %p\n", - (const void*)(uintptr_t)test_main); - printf("KernAux_StackTrace_Frame_create: %p\n\n", - (const void*)(uintptr_t)KernAux_StackTrace_Frame_create); - PREPARE("test_main (initial)", min, MIN); PREPARE("test_main (compare)", max, MAX); From 7b052cd75085c017a8aa1613a77836cf64438a1d Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sun, 4 Dec 2022 00:43:30 +0400 Subject: [PATCH 27/34] Add test case --- tests/test_stack_trace.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/test_stack_trace.c b/tests/test_stack_trace.c index 43383bbb..7121bf02 100644 --- a/tests/test_stack_trace.c +++ b/tests/test_stack_trace.c @@ -41,6 +41,8 @@ static const void *max_addresses[MAX_SIZE]; putchar('\n'); \ } while (0) +static void test1(); + void test_main() { PREPARE("test_main (initial)", min, MIN); @@ -50,4 +52,14 @@ void test_main() for (size_t index = 1; index < max_count; ++index) { assert(max_addresses[index] == min_addresses[index]); } + + test1(); + for (size_t index = 2; index < max_count; ++index) { + assert(max_addresses[index] == min_addresses[index - 1]); + } +} + +void test1() +{ + PREPARE("test1", max, MAX); } From 2868c17b96ce368c2ac512e692e15859050fec07 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sun, 4 Dec 2022 00:48:28 +0400 Subject: [PATCH 28/34] Add test case --- tests/test_stack_trace.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/tests/test_stack_trace.c b/tests/test_stack_trace.c index 7121bf02..b78171bc 100644 --- a/tests/test_stack_trace.c +++ b/tests/test_stack_trace.c @@ -43,6 +43,12 @@ static const void *max_addresses[MAX_SIZE]; static void test1(); +static void test5_1(); +static void test5_2(); +static void test5_3(); +static void test5_4(); +static void test5_5(); + void test_main() { PREPARE("test_main (initial)", min, MIN); @@ -57,9 +63,17 @@ void test_main() for (size_t index = 2; index < max_count; ++index) { assert(max_addresses[index] == min_addresses[index - 1]); } -} -void test1() -{ - PREPARE("test1", max, MAX); + test5_1(); + for (size_t index = 6; index < max_count; ++index) { + assert(max_addresses[index] == min_addresses[index - 5]); + } } + +void test1() { PREPARE("test1", max, MAX); } + +void test5_1() { test5_2(); } +void test5_2() { test5_3(); } +void test5_3() { test5_4(); } +void test5_4() { test5_5(); } +void test5_5() { PREPARE("test5_5", max, MAX); } From f62581a5ceaf451a644b3dbc432af9dd64b2a465 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sun, 4 Dec 2022 00:54:37 +0400 Subject: [PATCH 29/34] Fix cppcheck --- tests/test_stack_trace.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_stack_trace.c b/tests/test_stack_trace.c index b78171bc..371b90d4 100644 --- a/tests/test_stack_trace.c +++ b/tests/test_stack_trace.c @@ -33,8 +33,9 @@ static const void *max_addresses[MAX_SIZE]; assert(lower##_count < upper##_SIZE); \ lower##_addresses[lower##_count] = \ KernAux_StackTrace_Frame_get_ptr(&frame); \ - printf(" %lu: 0x%p\n", \ - lower##_count, lower##_addresses[lower##_count]); \ + printf(" %llu: 0x%p\n", \ + (unsigned long long)lower##_count, \ + lower##_addresses[lower##_count]); \ ++lower##_count; \ } \ \ From 6c5d7d0b3a97c23e0073d1acb5d1f658775a8a89 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sun, 4 Dec 2022 00:56:30 +0400 Subject: [PATCH 30/34] Rename func --- include/kernaux/stack_trace.h | 2 +- src/stack_trace.c | 2 +- tests/test_stack_trace.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/kernaux/stack_trace.h b/include/kernaux/stack_trace.h index 54e1f162..bfcb4bf6 100644 --- a/include/kernaux/stack_trace.h +++ b/include/kernaux/stack_trace.h @@ -17,7 +17,7 @@ typedef struct KernAux_StackTrace_Frame { struct KernAux_StackTrace_Frame KernAux_StackTrace_Frame_create(); -bool KernAux_StackTrace_Frame_has_more(KernAux_StackTrace_Frame frame); +bool KernAux_StackTrace_Frame_has_next(KernAux_StackTrace_Frame frame); void KernAux_StackTrace_Frame_use_next(KernAux_StackTrace_Frame frame); const void *KernAux_StackTrace_Frame_get_ptr(KernAux_StackTrace_Frame frame); diff --git a/src/stack_trace.c b/src/stack_trace.c index bebbd7f4..7681f819 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -30,7 +30,7 @@ struct KernAux_StackTrace_Frame KernAux_StackTrace_Frame_create() return frame; } -bool KernAux_StackTrace_Frame_has_more(const KernAux_StackTrace_Frame frame) +bool KernAux_StackTrace_Frame_has_next(const KernAux_StackTrace_Frame frame) { KERNAUX_ASSERT(frame); diff --git a/tests/test_stack_trace.c b/tests/test_stack_trace.c index 371b90d4..02979a09 100644 --- a/tests/test_stack_trace.c +++ b/tests/test_stack_trace.c @@ -27,7 +27,7 @@ static const void *max_addresses[MAX_SIZE]; for ( \ struct KernAux_StackTrace_Frame frame = \ KernAux_StackTrace_Frame_create(); \ - KernAux_StackTrace_Frame_has_more(&frame); \ + KernAux_StackTrace_Frame_has_next(&frame); \ KernAux_StackTrace_Frame_use_next(&frame) \ ) { \ assert(lower##_count < upper##_SIZE); \ From 03589f484484281d7d8fac37dac6d1b9927b2ff7 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sun, 4 Dec 2022 01:02:43 +0400 Subject: [PATCH 31/34] Rename field --- include/kernaux/stack_trace.h | 2 +- src/stack_trace.c | 24 +++++++++++++----------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/include/kernaux/stack_trace.h b/include/kernaux/stack_trace.h index bfcb4bf6..137856e6 100644 --- a/include/kernaux/stack_trace.h +++ b/include/kernaux/stack_trace.h @@ -12,7 +12,7 @@ extern "C" { #include typedef struct KernAux_StackTrace_Frame { - const void *KERNAUX_PRIVATE_FIELD(ptr); + const void *KERNAUX_PRIVATE_FIELD(cur_ptr); } *KernAux_StackTrace_Frame; struct KernAux_StackTrace_Frame KernAux_StackTrace_Frame_create(); diff --git a/src/stack_trace.c b/src/stack_trace.c index 7681f819..08610af5 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -19,12 +19,14 @@ struct KernAux_StackTrace_Frame KernAux_StackTrace_Frame_create() { - struct KernAux_StackTrace_Frame frame = { .ptr = NULL }; + struct KernAux_StackTrace_Frame frame = { .cur_ptr = NULL }; #if defined(ASM_I386) - KERNAUX_ASM("movl %%ebp, %0" : "=g"((const size_t*)frame.ptr) :: "memory"); + KERNAUX_ASM("movl %%ebp, %0" + : "=g"((const size_t*)frame.cur_ptr) :: "memory"); #elif defined(ASM_X86_64) - KERNAUX_ASM("movq %%rbp, %0" : "=g"((const size_t*)frame.ptr) :: "memory"); + KERNAUX_ASM("movq %%rbp, %0" + : "=g"((const size_t*)frame.cur_ptr) :: "memory"); #endif return frame; @@ -34,11 +36,11 @@ bool KernAux_StackTrace_Frame_has_next(const KernAux_StackTrace_Frame frame) { KERNAUX_ASSERT(frame); - if (!frame->ptr) return false; + if (!frame->cur_ptr) return false; #if defined(ASM_X86) - const size_t *const ptr = frame->ptr; - return ptr[1]; + const size_t *const cur_ptr = frame->cur_ptr; + return cur_ptr[1]; #else return false; #endif @@ -48,11 +50,11 @@ void KernAux_StackTrace_Frame_use_next(const KernAux_StackTrace_Frame frame) { KERNAUX_ASSERT(frame); - if (!frame->ptr) return; + if (!frame->cur_ptr) return; #if defined(ASM_X86) - const size_t *const ptr = frame->ptr; - frame->ptr = (const void*)ptr[0]; + const size_t *const cur_ptr = frame->cur_ptr; + frame->cur_ptr = (const void*)cur_ptr[0]; #endif } @@ -62,8 +64,8 @@ const void *KernAux_StackTrace_Frame_get_ptr( KERNAUX_ASSERT(frame); #if defined(ASM_X86) - const size_t *const ptr = frame->ptr; - return (const void*)ptr[1]; + const size_t *const cur_ptr = frame->cur_ptr; + return (const void*)cur_ptr[1]; #else return NULL; #endif From 025667f1d4a0749d4b4e66da78b34c6a03413a13 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sun, 4 Dec 2022 01:15:41 +0400 Subject: [PATCH 32/34] Fix error --- src/stack_trace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/stack_trace.c b/src/stack_trace.c index 08610af5..002247d4 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -22,11 +22,11 @@ struct KernAux_StackTrace_Frame KernAux_StackTrace_Frame_create() struct KernAux_StackTrace_Frame frame = { .cur_ptr = NULL }; #if defined(ASM_I386) - KERNAUX_ASM("movl %%ebp, %0" - : "=g"((const size_t*)frame.cur_ptr) :: "memory"); + const size_t *cur_ptr = frame.cur_ptr; + KERNAUX_ASM("movl %%ebp, %0" : "=g" (cur_ptr) :: "memory"); #elif defined(ASM_X86_64) - KERNAUX_ASM("movq %%rbp, %0" - : "=g"((const size_t*)frame.cur_ptr) :: "memory"); + const size_t *cur_ptr = frame.cur_ptr; + KERNAUX_ASM("movq %%rbp, %0" : "=g" (cur_ptr) :: "memory"); #endif return frame; From eae451ee754ee44ae0d0c70a4e338624ff94cc97 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sun, 4 Dec 2022 01:22:31 +0400 Subject: [PATCH 33/34] Fix bug --- src/stack_trace.c | 6 ++++-- tests/test_stack_trace.c | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/stack_trace.c b/src/stack_trace.c index 002247d4..2421f929 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -22,11 +22,13 @@ struct KernAux_StackTrace_Frame KernAux_StackTrace_Frame_create() struct KernAux_StackTrace_Frame frame = { .cur_ptr = NULL }; #if defined(ASM_I386) - const size_t *cur_ptr = frame.cur_ptr; + const size_t *cur_ptr; KERNAUX_ASM("movl %%ebp, %0" : "=g" (cur_ptr) :: "memory"); + frame.cur_ptr = cur_ptr; #elif defined(ASM_X86_64) - const size_t *cur_ptr = frame.cur_ptr; + const size_t *cur_ptr; KERNAUX_ASM("movq %%rbp, %0" : "=g" (cur_ptr) :: "memory"); + frame.cur_ptr = cur_ptr; #endif return frame; diff --git a/tests/test_stack_trace.c b/tests/test_stack_trace.c index 02979a09..8381a910 100644 --- a/tests/test_stack_trace.c +++ b/tests/test_stack_trace.c @@ -39,6 +39,7 @@ static const void *max_addresses[MAX_SIZE]; ++lower##_count; \ } \ \ + assert(lower##_count >= 2); \ putchar('\n'); \ } while (0) From 1395896538bbe00a07f9d8d2a5f7c1e49490651b Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sun, 4 Dec 2022 01:26:58 +0400 Subject: [PATCH 34/34] Protect from segfault --- src/stack_trace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/stack_trace.c b/src/stack_trace.c index 2421f929..84e6d6ba 100644 --- a/src/stack_trace.c +++ b/src/stack_trace.c @@ -65,6 +65,8 @@ const void *KernAux_StackTrace_Frame_get_ptr( ) { KERNAUX_ASSERT(frame); + if (!frame->cur_ptr) return NULL; + #if defined(ASM_X86) const size_t *const cur_ptr = frame->cur_ptr; return (const void*)cur_ptr[1];