This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] Python Finish Breakpoints


Kevin Pouget wrote:

> 	* gdb.python/py-finish-breakpoint2.cc: New file.
> 	* gdb.python/py-finish-breakpoint2.exp: New file.
> 	* gdb.python/py-finish-breakpoint2.py: New file.

I'm seeing those fail on various platforms (i386, ppc, ppc64):
FAIL: gdb.python/py-finish-breakpoint2.exp: check FinishBreakpoint in catch()
FAIL: gdb.python/py-finish-breakpoint2.exp: check finish BP removal
FAIL: gdb.python/py-finish-breakpoint2.exp: continue to second exception
FAIL: gdb.python/py-finish-breakpoint2.exp: set FinishBP after the exception

However in other cases the test succeeds -- this appears to be related to
the particular compiler version that's being used.

The problem is that the finish-breakpoint mechanism sets a breakpoint on
the regular return address of the current frame, i.e. the instruction
where the "call" instruction would return normally.  However, when an
exception is thrown and then caught, execution continues at a different
call site (in the catch block).  There's now two possibilities:

  try
    {
      throw_exception_1 (10);
    }
  catch (const int *e)
    {
        std::cerr << "Exception #" << *e << std::endl;
    }
  i += 1; /* Break after exception 1.  */


A) The instruction immediately following the "call" instruction to
   throw_exception_1 is actually already one of the instructions used
   to implement the "i += 1" line, and code flow after executing the
   catch block branches back to that location.  I.e. we have a call
   graph along the lines of:

   [...]
       call throw_exception_1 (10)  [ set up catch block at Lc ]
   Lx: compute i += 1
   [...]

   Lc: call std:cerr << ...
       goto Lx

  and the finish breakpoint gets set just at label Lx, and it will
  get hit both after a regular return and after an exception.

B) The instruction immediately following the "call" instruction
   is still part of the (clean up after the) call, or some other
   code flow instruction, and the instructions used to implement
   "i += 1" are elsewhere.  I.e. the call graph looks more like:

   [...]
       call throw_exception_1 (10)  [ set up catch block at Lc ]
   Lx: goto Ly
  
   Lc: call std:cerr <<< ...

   Ly: compute i += 1
   [...]

   In this case the finish breakpoint gets set at Lx, which *never*
   gets executed after an exception.


It seems to me that current GDB code does not (even attempt to) properly
handle the "finish" command and/or the new finish-breakpoint capability
in the presence of exceptions.  Note that even in case A) above, where
the finish breakpoint does hit, it arguably hits in the wrong location:
at the "finish" of the throw_exception_1 line, execution continues *in
the catch block*, so we should stop at the start of the catch block
instead of after it has completed.

Am I missing some piece of GDB code that attempts to handle this, and
is just malfunctioning?  It would certainly be good to properly support
this feature, but until we do, I'd suggest this test case should be
disabled ...

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]