This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
RE: [BUG] Quit and "(running)" problem
Thanks for the explanations...
By the way, this also explains why I
got troubles when I tried some code
with windows OS, where I added some
debug informations using printf_unfiltered into the windows
function that handles console control events.
The problem was that even printf_unfiltered
adds some cleanups, but this control function
is executed in a newly created thread, which
leads to big troubles, if a second control event
is generated...
Pierre Muller
Pascal language support maintainer for GDB
> -----Message d'origine-----
> De?: Pedro Alves [mailto:pedro@codesourcery.com]
> Envoyé?: Friday, January 16, 2009 4:13 PM
> À?: Pierre Muller
> Cc?: 'Joel Brobecker'; gdb-patches@sourceware.org
> Objet?: Re: [BUG] Quit and "(running)" problem
>
> A Friday 16 January 2009 08:54:21, Pierre Muller wrote:
> > I can confirm that your patch fixed the simple
> > test case that I submitted in PR9747.
>
> Thank you.
>
> > Reading the patch, I was wondering about the
> > utility of the old_chain cleanup in fetch_inferior_event
> > function. But this is probably due to my
> > lack of comprehension of the cleanup chain mechanisms.
> >
> > Is it really possible to reach
> > do_cleanups (old_chain)
> > with something else that old_chain
> > as the top item on the cleanup list?
>
> Yes, there's a make_cleanup_restore_current_thread call
> there that adds a new cleanup to the chain.
>
> > I thought that all the cleanups where stored
> > as local variables, so that all cleanups
> > that were set in functions called while running any
> > code called from within the fetch_inferior_event
> > would be invalid data anyhow at that point,
> > as the stack might have been overwritten by calls to other functions.
>
> Some confusion here. Instead of trying to explain the basic mechanism
> and doing a lousy job at it, I suggest taking a look at the Cleanups
> section
> in internals manual, if you haven't already, which I think explains
> it quite nicelly:
>
> http://sourceware.org/gdb/current/onlinedocs/gdbint_15.html#SEC118
>
> Another way to really understand cleanups is to step through
> the make_cleanup, do_cleanups and discard_cleanups functions, it looks
> scarrier than it is.
>
>
> In this particular case, we have:
>
> old_chain +----+- <null_cleanup>
> |
> +- <restore_current_thread> (always run this, wether
> leaving with an exception or leaving succesfully)
> |
> ts_old_chain +-+- <finish_thread_state> (only run if there's an
> exception)
>
> [do something that can throw]
>
> [ if we got pass it sucessfully, discard the
> <finish_thread_state> cleanup chain ]
>
> /* No error, don't finish the thread states yet. */
> discard_cleanups (ts_old_chain);
>
> So, at this point we have something like:
>
> old_chain +----+- <null_cleanup>
> |
> +- <restore_current_thread> (always run this, wether
> leaving with an exception or leaving succesfully)
>
> ts_old_chain (invalid, dangling pointer)
>
> /* Revert thread and frame. */
> do_cleanups (old_chain);
>
> This statement runs the <restore_current_thread>
> cleanup.
>
> ( I mentioned doing a lousy job explaining it. )
>
> --
> Pedro Alves