From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30758 invoked by alias); 2 Dec 2004 22:46:31 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 29967 invoked from network); 2 Dec 2004 22:46:13 -0000 Received: from unknown (HELO priv-edtnes51.telusplanet.net) (199.185.220.223) by sourceware.org with SMTP; 2 Dec 2004 22:46:13 -0000 Received: from takamaka.act-europe.fr ([142.179.108.108]) by priv-edtnes51.telusplanet.net (InterMail vM.6.01.03.02 201-2131-111-104-20040324) with ESMTP id <20041202224612.BAQR25051.priv-edtnes51.telusplanet.net@takamaka.act-europe.fr>; Thu, 2 Dec 2004 15:46:12 -0700 Received: by takamaka.act-europe.fr (Postfix, from userid 507) id EBC2B47DA6; Thu, 2 Dec 2004 14:46:06 -0800 (PST) Date: Thu, 02 Dec 2004 22:46:00 -0000 From: Joel Brobecker To: Andrew Cagney Cc: gdb-patches@sources.redhat.com Subject: [RFC] Infinite backtraces... Message-ID: <20041202224606.GL994@adacore.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4i X-SW-Source: 2004-12/txt/msg00051.txt.bz2 Hello, I have been studying the few examples I have here where GDB creates an endless backtrace when we do a "bt". There is also the case that Randolph exposed, but I think his case was a bit particular. Still staying on hppa, I have the following example (code copied at the end of this message). What the code does is create one task that will call a null procedure Break_Me. We put the breakpoint on that procedure, and run until we hit that breakpoint, and then do a backtrace. Because we're inside a task, the call stack does not start at the entry point nor does it contain a call to the "main" procedure. The current output is an endless callstack: (gdb) b break_me Breakpoint 1 at 0xa32c: file simple.adb, line 27. (gdb) run Starting program: /[...]/simple [New thread 2 (system thread 25946)] [Switching to thread 2 (system thread 25946)] Breakpoint 1, simple.break_me () at simple.adb:27 27 end Break_Me; (gdb) bt 20 #0 simple.break_me () at simple.adb:27 #1 0x0000a2cc in simple.caller (<_task>=0x4001c3a0) at simple.adb:21 #2 0x0000a268 in simple__callerB___2 () at simple.adb:18 #3 0x00017184 in system.tasking.stages.task_wrapper () #4 0x00017058 in system__tasking__stages__task_wrapper () #5 0x7aee0f60 in __pthread_create_system () from /usr/lib/libpthread.1 #6 0x7aee0f08 in __pthread_create_system () from /usr/lib/libpthread.1 #7 0x00000000 in ?? () #8 0x7aee0f08 in __pthread_create_system () from /usr/lib/libpthread.1 #9 0x00000000 in ?? () #10 0x7aee0f08 in __pthread_create_system () from /usr/lib/libpthread.1 #11 0x00000000 in ?? () #12 0x7aee0f08 in __pthread_create_system () from /usr/lib/libpthread.1 #13 0x00000000 in ?? () #14 0x7aee0f08 in __pthread_create_system () from /usr/lib/libpthread.1 #15 0x00000000 in ?? () #16 0x7aee0f08 in __pthread_create_system () from /usr/lib/libpthread.1 #17 0x00000000 in ?? () #18 0x7aee0f08 in __pthread_create_system () from /usr/lib/libpthread.1 #19 0x00000000 in ?? () (More stack frames follow...) I am not sure I have a sufficiently high-level view of the entire code that is involved in unwinding, but it seemed to me that we need to add a new architecture-dependent hook that would tell whether a given frame is the initial one, and that unwinding can not be done past this frame. This naturally pointed to a new gdbarch method. Something like gdbarch_upper_most_frame_p (....), with a default value that would always return false. And then, in get_prev_frame_1, either right after we check for this_frame->prev_p, or slightly after we get the ID of this_frame, we can add a call to this new method. I am still doing some researching about this, but I think that on hppa, the RP will always be initialized to 0 in the upper most frame. So we can stop the unwinding using that condition. What do you think? Thanks, -- Joel procedure Simple is ------------------- -- Declaractions -- ------------------- task type Caller is end Caller; type Caller_Ptr is access Caller; procedure Break_Me; My_Caller : Caller_Ptr; ------------ -- Bodies -- ------------ task body Caller is begin Break_Me; end Caller; procedure Break_Me is begin null; end Break_Me; begin My_Caller := new Caller; end Simple;