Author Topic: gdb stop on c++ exceptions  (Read 15472 times)

Offline Ingrater

  • Single posting newcomer
  • *
  • Posts: 7
gdb stop on c++ exceptions
« on: April 22, 2008, 01:53:46 pm »
I'm trying to make the gdb debugger to stop on c++ exceptions so I've read the gdb manual. I've found an advice there to set a breakpoint on the ansi c __raise_exception function to catch possible exceptions exactly were they are thrown. Unfortunately I have no clue how to achieve this inside the Code::Blocks IDE. I'm Using Code::Blocks on Windows with MinGW and GDB.

Thanks in advance.

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: gdb stop on c++ exceptions
« Reply #1 on: April 22, 2008, 06:58:21 pm »
Did you try typing "break __raise_exception" into the "send user command to debugger" thingie (last menu item in debug menu)?

Granted, that's about the most inconvenient way of setting a breakpoint, but I don't think there's another way right now.

Yiannis, does the debugger plugin export functions for scripts? If so, that could be a 2-liner script plugin...
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline Ingrater

  • Single posting newcomer
  • *
  • Posts: 7
Re: gdb stop on c++ exceptions
« Reply #2 on: April 22, 2008, 07:33:53 pm »
Tried "catch throw" and "break __raise_exception"
Both had absoluty no effect.

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: gdb stop on c++ exceptions
« Reply #3 on: April 22, 2008, 07:47:11 pm »
You could try adding the command Thomas gave you to "Settings->Compiler and debugger->Debugger->initialization commands".

Though you might have a hard time finding the exact function to break. For example, in my case (linux), I had to add "break __cxa_throw".
Be patient!
This bug will be fixed soon...

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: gdb stop on c++ exceptions
« Reply #4 on: April 22, 2008, 08:03:29 pm »
Quote
"break __cxa_throw"
Same here (MinGW-gcc 4.2-DW2), however, unluckily it doesn't work so well.
It does interrupt the program, but you can't do much but continue (or step onward). For some reason, the debugger plugin doesn't wake up and show the current line, nor disassemble or update watches.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: gdb stop on c++ exceptions
« Reply #5 on: April 22, 2008, 08:07:52 pm »
__cxa_end_catch almost works.
If you hit "step to next line" after breaking on that, it stops right after the catch clause, and the debugger wakes up and everything looks nicely.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: gdb stop on c++ exceptions
« Reply #6 on: April 22, 2008, 08:19:43 pm »
... and I know why it doesn't work.

list __cxa_throw
No line number known for __cxa_throw.


The symbol __cxa_throw has no corresponding line in the source file. So although the debugger will break on it, it won't find it.

However:
info line *4199509
Line 10 of "D:\devel\ex\main.cpp" starts at address 0x401455 <main+53> and ends at 0x401483 <main+99>.
D:\devel\ex\main.cpp:10:103:beg:0x401455
At D:\devel\ex\main.cpp:10


So, the debugger plugin would need a little update, taking the value of EIP and query the line number like this.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline Ingrater

  • Single posting newcomer
  • *
  • Posts: 7
Re: gdb stop on c++ exceptions
« Reply #7 on: April 23, 2008, 12:28:18 pm »
It does work now, but it doesn't result in a backtrace I could use. So I'm staying for the moment with manually creating an backtrace interrupt until I find a better solution.

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: gdb stop on c++ exceptions
« Reply #8 on: April 23, 2008, 02:00:56 pm »
I've been playing with this for a bit, since I said "oh heck, this would be immensely helpful"... but there seems to be no safe way to get it to work every time.
Breaking on __cxa_throw... no problem.
Getting EIP and dumping the disassembly... no problem.
Dumping any other registers... no problem.
Finding the source line number... works 50% of the time, and doesn't 50% of the time.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: gdb stop on c++ exceptions
« Reply #9 on: April 24, 2008, 09:55:30 am »
Reading the documentation reveals that gdb has a dedicated, standard command to catch exceptions.
catch throw will break when an exception is thrown just before the stack is unwound (there are other commands for breaking after unwinding too, but those are less useful). It works just fine, except the debugger plugin doesn't find a source line number, since the exception doesn't have one.

info frame shows __cxa_throw as the first entry, and the containing function, address and line number where the throw statement can be found in the second entry. It works surprisingly well. Ok, actually, since the entire exception handling is built on top of that, that's not surprising at all, duh :)

So, to make breaking on exceptions really work (including setting the little yellow wedge on the source line), the debugger plugin would have to:
1. send catch throw at startup
2. do everything as usual when waking up, but if frame[0] has no line number and is called __cxa_throw (or maybe match against something more permissive, such as /__.*throw/ ), use the line number of frame[1] instead.
« Last Edit: April 24, 2008, 10:46:20 am by thomas »
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: gdb stop on c++ exceptions
« Reply #10 on: April 24, 2008, 11:34:48 am »
We could do as many hacks as we want to locate the source line of interest but, please, do _not_ display the line indicator (yellow arrow) on the wrong function. That is supposed to show the line that would be executed next, not one (or more) frames back in execution time...
« Last Edit: April 24, 2008, 11:36:29 am by mandrav »
Be patient!
This bug will be fixed soon...

Offline mandrav

  • Project Leader
  • Administrator
  • Lives here!
  • *****
  • Posts: 4315
    • Code::Blocks IDE
Re: gdb stop on c++ exceptions
« Reply #11 on: April 24, 2008, 12:58:16 pm »
We could do as many hacks as we want to locate the source line of interest but, please, do _not_ display the line indicator (yellow arrow) on the wrong function. That is supposed to show the line that would be executed next, not one (or more) frames back in execution time...

Oh well, no need to argue about that. I added two new debugger options:
  • Catch C++ exceptions, and
  • When breaking, auto-switch to first frame with valid source info


In r5018 :).

Note that even if auto-switch is off, the debugger will still "focus" on the first valid source line in the stack frame. It's just that the frame won't be switched.

Another note: this auto-switch stuff will work for any reason the debugger would break, not just C++ exceptions ;).
« Last Edit: April 24, 2008, 01:01:30 pm by mandrav »
Be patient!
This bug will be fixed soon...

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: gdb stop on c++ exceptions
« Reply #12 on: April 24, 2008, 02:26:00 pm »
Works great most of the time, thank you :) Sometimes, it seems to have no valid frame at all, though I can't reproduce why and when. Other than that: cool, really cool.

Putting the arrow at the previous frame is incorrect behaviour, that's right, but for the particular case of breaking on an exception, it's immensely useful being pointed to "here, there be exception". So since we don't have another marker (like a small flaming "E" or something), I guess that can be excused :)
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."