]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit - gdb/ada-lang.c
[Ada] avoid error message pollution with uninitialized tagged variable
authorJoel Brobecker <brobecker@gnat.com>
Wed, 29 Feb 2012 19:46:48 +0000 (19:46 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Wed, 29 Feb 2012 19:46:48 +0000 (19:46 +0000)
commit1b61134393256db280b968d24ddf7bb22b6aabcc
tree9c4bf66e9db573f2eb507eedb0fa8a6b4b8bb41b
parent41246937ec25e4d69802ee153ce8c562882126a1
[Ada] avoid error message pollution with uninitialized tagged variable

Consider the following function...

  3 procedure Foo is
  4    I : Integer := Ident (10);
  5    Obj : Base;
  6 begin
  7    Obj.X := I;
  8    Do_Nothing (Obj.X'Address);
  9 end Foo;

... where type "Base" is defined as a plain tagged record. If the user
stops execution before "Obj" gets initialized (for example, by inserting
a breakpoint "on" the function - or in other words, by inserting a
breakpoint using the function name as the location), one might get
the following of output if you try printing the value of obj:

    (gdb) p obj
    object size is larger than varsize-limit
    object size is larger than varsize-limit
    object size is larger than varsize-limit
    $1 = object size is larger than varsize-limit
    (x => 4204154)

Same thing with "info locals":

   (gdb) info locals
    i = 0
    obj = object size is larger than varsize-limit
    (x => 4204154)

We have also seen different error messages such as "Cannot read
memory at 0x...".

The error happens because we are trying to read the dispatch table
of a tagged type variable before it gets initialized.  So the errors
might legitimately occur, and are supposed to be be contained.
However, the way things are written in ada-lang.c:ada_tag_name,
although the exception is in fact contained, the error message still
gets to be printed out.

This patch prevents this from happening by eliminating the use of
catch_errors, and using a TRY_CATCH block instead.  Doing this removed
the need to use functions specifically fitted for catch_errors, and
thus some other simplifications could me made.  In the end, the code
got reorganized a bit to better show the logic behind it, as well as
the common patterns.

gdb/ChangeLog:

        * ada-lang.c (struct tag_args): Delete.
        (ada_get_tsd_type): Function body moved up in source file.
        (ada_tag_name_1, ada_tag_name_2): Delete.
        (ada_get_tsd_from_tag): New function.
        (ada_tag_name_from_tsd): New function.
        (ada_tag_name): Use a TRY_CATCH block instead of catch_errors
        to determine the tag name.

gdb/testsuite/ChangeLog:

        * gdb.ada/tagged_not_init: New testcase.
gdb/ChangeLog
gdb/ada-lang.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.ada/tagged_not_init.exp [new file with mode: 0644]
gdb/testsuite/gdb.ada/tagged_not_init/foo.adb [new file with mode: 0644]
gdb/testsuite/gdb.ada/tagged_not_init/pck.adb [new file with mode: 0644]
gdb/testsuite/gdb.ada/tagged_not_init/pck.ads [new file with mode: 0644]