From 40cc0ebde28b0e56dd087583b6a40936d518d845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 4 Oct 2004 22:52:56 +0000 Subject: [PATCH] Added an endless loop detection; it will now store up to 16 stack positions and will check against those. This fixes the rare case an interrupt frame could cause before. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9191 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/core/arch/x86/arch_debug.c | 32 ++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/kernel/core/arch/x86/arch_debug.c b/src/kernel/core/arch/x86/arch_debug.c index a366ee56f8..87d44ba0cb 100755 --- a/src/kernel/core/arch/x86/arch_debug.c +++ b/src/kernel/core/arch/x86/arch_debug.c @@ -16,12 +16,38 @@ #include +#define NUM_PREVIOUS_LOCATIONS 16 + + +static bool +already_visited(uint32 *visited, int32 *_last, int32 *_num, uint32 ebp) +{ + int32 last = *_last; + int32 num = *_num; + int32 i; + + for (i = 0; i < num; i++) { + if (visited[(NUM_PREVIOUS_LOCATIONS + last - i) % NUM_PREVIOUS_LOCATIONS] == ebp) + return true; + } + + *_last = last = (last + 1) % NUM_PREVIOUS_LOCATIONS; + visited[last] = ebp; + + if (num < NUM_PREVIOUS_LOCATIONS) + *_num = num + 1; + + return false; +} + + static int dbg_stack_trace(int argc, char **argv) { + uint32 previousLocations[NUM_PREVIOUS_LOCATIONS]; struct thread *t; uint32 ebp; - int i; + int32 i, num = 0, last = 0; if (argc < 2) t = thread_get_current_thread(); @@ -87,6 +113,10 @@ dbg_stack_trace(int argc, char **argv) ebp = *(uint32 *)ebp; } + if (already_visited(previousLocations, &last, &num, ebp)) { + dprintf("circular stack frame: %p!\n", (void *)ebp); + break; + } if (ebp == 0) break; }