Mirror of the gdb mailing list
 help / color / mirror / Atom feed
From: Roland Schwingel <roland.schwingel@onevision.de>
To: Joel Brobecker <brobecker@adacore.com>, gdb <gdb@sourceware.org>
Subject: Re: Strange stack trace on Windows
Date: Tue, 17 Mar 2009 11:58:00 -0000	[thread overview]
Message-ID: <49BF903D.6090900@onevision.de> (raw)

Hi....

I am following up on an old post from Joel Brobecker from october 2007 
regarding
strange stack traces on windows triggered by frameless functions (see 
below).
This is a real pain when using gdb on windows. You are seeing close to 
NOTHING
when you try to debug a crashing application on windows since gdb 6.0 
especially
when the executable is multithreaded.

With the patch from Joel I get really good strack traces back in this case.
This is really good news. I can also sacrifice the missing frame. It is 
way better
than the other case.

But there is mabye a sideeffect of this patch when stepping thru an 
application.
GDB sometimes steps inside of functions I don't want to step into. Maybe 
Joel
has a new version ready?

What happens - my scenario:
I have a tiny application (just outlined here to keep it short) loading 
nothing
else than a certain dll and continue exection there...
int main (int argc, char **argv)
{
    setbuf(stdout,NULL);
    setbuf(stderr,NULL);
   
    // Load shared library and continue there
    anotherDLLHandle  = LoadLibrary("another.dll");
    anotherDLLFunction = GetProcAdress(anotherDLLHandle ,"function");
    anotherDLLFunction();
    ..
}

Code from another.dll:
void function(void)
{
    ...
    setbuf(stdout,NULL);
    setbuf(stderr,NULL);
    ...
}

When I am stepping thru the app from main() without Joel's patch 
everything is fine
with stepping. When I use Joel's patch the following happens:
I can step correctly thru the app until I reach function() from another.dll.
As soon as I type next on one of the setbuf() functions gdb steps 
directly to
the assembly code of setbuf not over it as I would like to have it...

So what's wrong here? I would like to have correct stack traces AND 
correct stepping
thru my app on windows. IMHO should the stack trace issue be addressed 
in gdb
in general. In my eyes GDB should work as fine on windows as it does on 
eg. linux.
(BTW: I am using GDB from current CVS sources).

I attach the inital post from Joel containing the patch to my mail to 
get the right context.

Thanks in advance for your help!

Roland

Joel Brobecker wrote on 01.10.2007 16:39:06:
 > > Sometime yes, sometimes no. I implemented that solution abotu 6 months
 > > ago but backed it out because it was just as likely to crash gdb:-(
 > > or hang my IDE (netbeans).
 >
 > We have experienced the same type of problem at AdaCore, and decided
 > to make some compromises: We decided to trust the %ebp registers when
 > unwinding frameless functions from a DLL. This comes with a price:
 > We miss a frame in the backtrace. But because tasking is so important
 > in Ada, we felt it was a better compromise than not being able to unwind
 > from tasks that are blocked waiting for a rendez-vous.
 >
 > Which compromise is best actually depends on the user, which is why
 > this code, or a variation of it, never made it to the FSF tree.
 >
 > This is what our i386_frame_cache() does in case of frameless routines:
 >
 >   if (cache->locals < 0)
 >     {
 >       /* We didn't find a valid frame, which means that CACHE->base
 >          currently holds the frame pointer for our calling frame.  If
 >          we're at the start of a function, or somewhere half-way its
 >          prologue, the function's frame probably hasn't been fully
 >          setup yet.  Try to reconstruct the base address for the stack
 >          frame by looking at the stack pointer.  For truly "frameless"
 >          functions this might work too.  */
 >
 >       if (i386_in_dll (cache->pc)
 >           && !i386_function_has_frame (cache->pc))
 >         {
 >           /* Functions in DLL for which do not seem to create a standard
 >              frame are unwound using %ebp.  This is actually the caller's
 >              frame base instead of our own, but there are some functions
 >              such as WaitForSingleObjectEx in one of the Windows system
 >              DLLs for which the frame base cannot possibly be determined
 >              from the stack pointer.  As a consequence, our caller 
will be
 >              missing from the backtrace, but this is better than having
 >              an aborted backtrace due to a bogus frame base.
 >              
 >              We use this approach only for functions in DLLs because
 >              this is the only place where we have seen the type of
 >              highly optimized code that cause us trouble.  In other
 >              cases, we expect the code to come with frame debugging
 >              information, making prologue scanning unnecessary.
 >              
 >              We also avoid blindly following %ebp if we are midway 
through
 >              setting up a standard frame.  In that case, we know how to
 >              determine the frame base using the stack pointer.  */
 >
 >           cache->saved_regs[I386_EBP_REGNUM] = 0;
 >         }
 >       else
 >         {
 >           i386_frameless_adjust_cache_hack (cache, frame_pc_unwind 
(next_frame));
 >
 >           if (cache->stack_align)
 >             {
 >               /* We're halfway aligning the stack.  */
 >               cache->base = ((cache->saved_sp - 4) & 0xfffffff0) - 4;
 >               cache->saved_regs[I386_EIP_REGNUM] = cache->saved_sp - 4;
 >
 >               /* This will be added back below.  */
 >               cache->saved_regs[I386_EIP_REGNUM] -= cache->base;
 >             }
 >           else
 >             {
 >               frame_unwind_register (next_frame, I386_ESP_REGNUM, buf);
 >               cache->base = extract_unsigned_integer (buf, 4) + 
cache->sp_offset;
 >             }
 >         }
 >     }
 >
 > And the two helper functions are defined as:
 >
 > /* Return non-zero if the function starting at START_PC has a prologue
 >    that sets up a standard frame.  */
 >
 > static int
 > i386_function_has_frame (CORE_ADDR start_pc)
 > {
 >   struct i386_frame_cache cache;
 >
 >   cache.locals = -1;
 >   i386_analyze_prologue (start_pc, 0xffffffff, &cache);
 >
 >   return (cache.locals >= 0);
 > }
 >
 > /* Return non-zero if PC is inside one of the inferior's DLLs.  */
 >
 > static int
 > i386_in_dll (CORE_ADDR pc)
 > {
 >    char *so_name = solib_address (pc);
 >    int len;
 >
 >    if (so_name == NULL)
 >      return 0;
 >
 >    len = strlen (so_name);
 >    if (len < 5)
 >      return 0;
 >
 >    return ((so_name[len - 1] == 'l' || so_name[len - 1] == 'L')
 >            && (so_name[len - 2] == 'l' || so_name[len - 2] == 'L')
 >            && (so_name[len - 3] == 'd' || so_name[len - 3] == 'D')
 >            && so_name[len - 4] == '.');
 > }
 >
 >
 >
 > --
 > Joel
 >


             reply	other threads:[~2009-03-17 11:58 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-17 11:58 Roland Schwingel [this message]
2009-03-17 13:19 ` Joel Brobecker
  -- strict thread matches above, loose matches on Subject: below --
2009-03-23 13:12 Roland Schwingel
2009-03-18  9:26 Roland Schwingel
2009-03-19 14:18 ` Joel Brobecker
2009-03-17 15:39 Roland Schwingel
2009-03-17 19:43 ` Joel Brobecker
2009-03-17 15:26 Roland Schwingel
2009-03-17 13:49 Roland Schwingel
2009-03-17 14:27 ` Pedro Alves
2009-03-17 15:08 ` Joel Brobecker
2007-09-29 22:01 Gordon Prieur
2007-09-30  3:00 ` Daniel Jacobowitz
2007-09-30 18:13 ` Eli Zaretskii
2007-10-01 14:03   ` Gordon Prieur
2007-10-01 14:39     ` Joel Brobecker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=49BF903D.6090900@onevision.de \
    --to=roland.schwingel@onevision.de \
    --cc=brobecker@adacore.com \
    --cc=gdb@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox