What is the meaning of the 200 __clone lines in backtraces?

Daniel Santos daniel.santos at pobox.com
Thu Nov 26 16:22:29 CST 2015


On 11/26/2015 03:40 PM, Qian Hong wrote:
> Hi Bruno,
>
> On Fri, Nov 27, 2015 at 12:36 AM, Bruno Jesus <00cpxxx at gmail.com> wrote:
>> Up to 200. Is this a bug or it is just not possible to identify when
>> the backtrace ends and 200 is a hard limit or what else could it be?
> 'Up to 200' is limited by WineDbg
>
> stack.c:
> 185  * Do a backtrace on the current thread
> 186  */
> 187 unsigned stack_fetch_frames(const CONTEXT* _ctx)
>
> 239         if (nf > 200 || !ret) break;
>
> There is also:
> dbg.tab.c:/* YYINITDEPTH -- initial size of the parser's stacks.  */
> dbg.tab.c:#ifndef YYINITDEPTH
> dbg.tab.c:# define YYINITDEPTH 200
>
> However, I'm also curious by repeat of '__clone', I don't understand
> this part, hopefully someone else can explain it ;-)

Funny timing on this question. I've had a patch for this sitting in my local branch for a month or so and finally submitted it last night (attached). My guess has always been that when a process is forked (since that's how Linux babies are made) that something wasn't reading that stack frame correctly and just looped it. The call to clone would have happened in the process that spawned us, like /bin/bash if you started it from a bash shell.

There's likely a cleaner approach than this patch, but this one at least makes "backtrace all" readable for me.

Daniel


-------------- next part --------------
>From d4e80308c347a000db4bae59aeb873d1364f72c8 Mon Sep 17 00:00:00 2001
From: Daniel Santos <daniel.santos at pobox.com>
Date: Fri, 13 Nov 2015 19:36:40 -0600
Subject: winedbg: suppress bogus clone() frames in backtrace

Signed-off-by: Daniel Santos <daniel.santos at pobox.com>
---
 programs/winedbg/stack.c | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/programs/winedbg/stack.c b/programs/winedbg/stack.c
index f49480a..8ef2dbc 100644
--- a/programs/winedbg/stack.c
+++ b/programs/winedbg/stack.c
@@ -307,6 +307,11 @@ static void stack_print_addr_and_args(int nf)
                     im.ModuleName, (DWORD_PTR)(ihsf.InstructionOffset - im.BaseOfImage));
 }
 
+static int addr_is_nonzero(const ADDRESS64 *addr)
+{
+    return addr->Offset && (addr->Mode != AddrModeFlat || addr->Segment);
+}
+
 /******************************************************************
  *		backtrace
  *
@@ -322,12 +327,24 @@ static void backtrace(void)
          dbg_curr_thread->curr_frame < dbg_curr_thread->num_frames;
          dbg_curr_thread->curr_frame++)
     {
-        dbg_printf("%s%d ", 
-                   (cf == dbg_curr_thread->curr_frame ? "=>" : "  "),
-                   dbg_curr_thread->curr_frame);
-        stack_print_addr_and_args(dbg_curr_thread->curr_frame);
+        const unsigned nf     = dbg_curr_thread->curr_frame;
+        const ADDRESS64 *addr = &dbg_curr_thread->frames[nf].addr_frame;
+
+        /* suppress bogus clone() frames from repeating */
+        if (nf > 0
+            && !addr_is_nonzero(addr)
+            && !addr_is_nonzero(&dbg_curr_thread->frames[nf - 1u].addr_frame)
+            && !memcmp(&dbg_curr_thread->frames[nf].addr_pc,
+                       &dbg_curr_thread->frames[nf - 1u].addr_pc,
+                       sizeof(dbg_curr_thread->frames[nf].addr_pc)))
+        {
+            break;
+        }
+
+        dbg_printf("%s%2u ", (cf == nf ? "=>" : "  "), nf);
+        stack_print_addr_and_args(nf);
         dbg_printf(" (");
-        print_bare_address(&dbg_curr_thread->frames[dbg_curr_thread->curr_frame].addr_frame);
+        print_bare_address(addr);
         dbg_printf(")\n");
     }
     /* reset context to current stack frame */
-- 
2.5.1



More information about the wine-devel mailing list