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]

[RFC/RFA] Add support for catch Ada exceptions


Hello,

Here is a patch that adds support for "catch"-ing Ada exceptions.
There are 3 different kinds of commands I am introducing:

  - catch exception [exception name]
    If the exception name is omitted, then all Ada exception are caught.

  - catch exception unhandled
    This catchpoint will stop if the program raises an exception
    that is not handled (and eventually causes the task or program death)

  - catch exception assert
    This catchpoint stops the program when assertions in the program
    fail. With GNAT, they are inserted like this:

        [code]
        pragma Assert (boolean_EXPRESSION);
        [code]

    They are activated only if the unit was compiled with assertions
    enabled.

Here is a typical GDB session debugging a program that does the
following:

    1. Raise exception Constraint_Error (and contain it)
    2. Raise exception Program_Error (and contain it)
    3. Fails an assertion (and contain it)
    4. Raise Constraint_Error (unhandled exception, program death)

We'll first catch all exceptions, and see how it catches them for
the first two exceptions:

    (gdb) catch exception
    Catchpoint 1 on all Ada exceptions at 0x804b7c0
    (gdb) info break
    Num Type           Disp Enb Address    What
    1   catch exception keep y   0x0804b7c0 on all Ada exceptions
    (gdb) run
    Starting program: /[...]/foo 
    
    Catchpoint 1, CONSTRAINT_ERROR at 0x08049813 in foo () at foo.adb:5
    5             raise Constraint_Error;  -- SPOT1
    (gdb) c
    Continuing.
    
    Catchpoint 1, PROGRAM_ERROR at 0x08049882 in foo () at foo.adb:12
    12            raise Program_Error;  -- SPOT2

As you see, the catchpoint notification message prints the catchpoint
number that was hit, displays the name of the exception that was raised,
and then the user location where the exception was raised.

In terms of implementation, these catchpoints are implemented using
breakpoints inside known functions of the GNAT runtime. However,
when we stop at these breakpoints, it would be confusing to the user
to leave them there. This is why, after the catchpoint hit, we go up
the stack automatically, and find the first "printable" frame, that
is a frame that is not part of the GNAT runtime and that has debugging
info (see ada_find_printable_frame).

For our last example, we'll catch only Program_Error, but also
failed assertions and unhandled exceptions:

    (gdb) catch exception program_error
    Catchpoint 1 on `program_error' Ada exception at 0x804b7c0
    (gdb) catch assert    
    Catchpoint 2 on failed Ada assertions at 0x804c437
    (gdb) catch exception unhandled
    Catchpoint 3 on unhandled Ada exceptions at 0x804ad2d
    (gdb) run
    Starting program: /[...]/foo 
    
    Catchpoint 1, PROGRAM_ERROR at 0x08049882 in foo () at foo.adb:12
    12            raise Program_Error;  -- SPOT2
    (gdb) c
    Continuing.
    
    Catchpoint 2, failed assertion at 0x080498f3 in foo () at foo.adb:19
    19            pragma Assert (False);  -- SPOT3
    (gdb) c
    Continuing.
    
    Catchpoint 3, unhandled CONSTRAINT_ERROR at 0x08049963 in foo () at foo.adb:26
    26         raise Constraint_Error;  -- SPOT4

The "info break" output looks like this:

    (gdb) info break
    Num Type           Disp Enb Address    What
    1   catch exception keep y   0x0804b7c0 on `program_error' Ada exception
    2   catch failed assertion keep y   0x0804c437 on failed Ada assertions
    3   catch unhandled exception keep y   0x0804ad2d on unhandled Ada exceptions

I already have a small testcase that tests the general functioning
of these catchpoins. I will also write some documentation, but I want
to make sure that at least the user-interface is agreed on before
I start this work.

2006-12-29  Joel Brobecker  <brobecker@adacore.com>

        * breakpoint.h (enum bptype): Add bp_catch_exception,
        bp_catch_unhandled_exception, and bp_catch_failed_assertion.
        * ada-lang.h (ada_find_printable_frame): Remove declaration.
        (ada_exception_sal): Add declaration.
        (ada_decode_exception_location): Likewise.
        * ada-lang.c: Add include of annotate.h and valprint.h.
        (function_name_from_pc): New function.
        (is_known_support_routine): New function.
        (ada_find_printable_frame): New function.
        (ada_unhandled_exception_name_addr): New function.
        (ada_exception_name_addr_1): New function.
        (ada_exception_name_addr): New function.
        (print_exception_catchpoint): New function.
        (print_one_exception_catchpoint): New function.
        (print_mention_exception_catchpoint): New function.
        (ada_exception_catchpoint_ops): New static variable.
        (error_breakpoint_runtime_sym_not_found): New function.
        (ada_get_next_arg): New function.
        (catch_ada_exception_command_split): New function.
        (ada_exception_catchpoint_cond_string): New function.
        (ada_parse_catchpoint_condition): New function.
        (ada_exception_sal): New function.
        (ada_decode_exception_location): New function.
        * breakpoint.c: Include ada-lang.h. Add support for Ada exception
        catchpoints throughout.
        (ep_is_ada_exception_catchpoint): New function.
        (create_ada_exception_breakpoint): New function.
        (catch_ada_exception_command): New function.
        (catch_assert_command): New function.
        (catch_command_1): Add handling for "exception" and "assert"
        subcommands.
        (_initialize_breakpoint): Update the documentation of "catch".
        * Makefile.in (ada-lang.o): Add dependency on annotate.h and
        valprint.h.
        (breakpoint.o): Add dependency on ada-lang.h.

2006-12-29  Joel Brobecker  <brobecker@adacore.com>

        * gdb.ada/catch_ex/foo.adb: New file.
        * gdb.ada/catch_ex.exp: New testcase.

Tested on x86-linux, no regressions.

Thank you!
-- 
Joel

Attachment: catch-except-v2.diff
Description: catch-except.diff

Attachment: foo.adb
Description: Text document

Attachment: catch_ex.exp
Description: Text document


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