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: [PATCH 4/5] Remove struct main_type.vptr_{fieldno,basetype}: TYPE_SPECIFIC_SELF_TYPE


  Hi all,

   I send to Doug in private an object file
together with the assembler file used to generate it for i386 mingw32 (PE object)
The source was compiled using Free Pascal compiler with -gs option
which generates stabs debugging information.
  ppc386 -gs -al -XX test.pas
(test.pas, test1.pas test2.pas and test2.inc are all source files).
  I don't know if sending binary object file to the mailing list is acceptable.


  Assembling test.s with a mingw32 target enabled assembler should work.
This is enough to trigger the internal error
using a Cygwin or mingw32 GDB (and should work on any platform if
compiled with --enable-targets=all.

  I checked with a i386-linux,
I get the same internal error (I just need to use 
set gnutarget pe-i386
before loading the file).

  I do not send the generated executable and the object is
less dangerous and already shows the problem for me,
and I hope also for you.

  Please find below a transcript of my test using this PE object:
I hope this will help you to understand more clearly what
I described in the previous email.

Pierre Muller

Pierre@E6510-Muller cygwin-32 ~/git/build/norm-cygwin32/gdb
$ ./gdb --args ./gdb ~/pas/trunk/fpcsrc/ide/test.o
GNU gdb (GDB) 7.9.50.20150205-cvs
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-cygwin".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./gdb...done.
Setting up the environment for debugging gdb.
Breakpoint 1 at 0x68c88c: file ../../../binutils-gdb/gdb/common/errors.c, line 54.
Breakpoint 2 at 0x4578d4: file ../../../binutils-gdb/gdb/cli/cli-cmds.c, line 217.
(top-gdb) r
Starting program: /home/Pierre/git/build/norm-cygwin32/gdb/gdb /home/Pierre/pas/trunk/fpcsrc/ide/test.o
[New Thread 2584.0xe1c]
[New Thread 2584.0x1478]
GNU gdb (GDB) 7.9.50.20150205-cvs
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-cygwin".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /home/Pierre/pas/trunk/fpcsrc/ide/test.o...done.
During symbol reading, incomplete CFI data; unspecified registers (e.g., eax) at 0x68c889.

Breakpoint 1, internal_error (file=0x7f4f8c <NS_INTEGER_POINTER_CONVERSION_BADNESS+204> "../../../binutils-gdb/gdb/gdbtypes.c", line=1204,
    fmt=0x7f4f5e <NS_INTEGER_POINTER_CONVERSION_BADNESS+158> "%s: Assertion `%s' failed.") at ../../../binutils-gdb/gdb/common/errors.c:54
54        va_start (ap, fmt);
(top-gdb) bt
#0  internal_error (file=0x7f4f8c <NS_INTEGER_POINTER_CONVERSION_BADNESS+204> "../../../binutils-gdb/gdb/gdbtypes.c", line=1204,
    fmt=0x7f4f5e <NS_INTEGER_POINTER_CONVERSION_BADNESS+158> "%s: Assertion `%s' failed.") at ../../../binutils-gdb/gdb/common/errors.c:54
#1  0x00570a5f in internal_type_self_type (type=0x801a8050) at ../../../binutils-gdb/gdb/gdbtypes.c:1204
#2  0x005e2d10 in read_member_functions (fip=0x2c2a354, pp=0x2c2a4c0, type=0x801a7f88, objfile=0x801568c8) at ../../../binutils-gdb/gdb/stabsread.c:2389
#3  0x005e578a in read_struct_type (pp=0x2c2a4c0, type=0x801a7f88, type_code=TYPE_CODE_STRUCT, objfile=0x801568c8) at ../../../binutils-gdb/gdb/stabsread.c:3555
#4  0x005e1f34 in read_type (pp=0x2c2a4c0, objfile=0x801568c8) at ../../../binutils-gdb/gdb/stabsread.c:2006
#5  0x005e0683 in define_symbol (valu=0,
    string=0x8018ec27 ":Tt2=s8Z:/038,0,32;$vf2:48,32;INIT::49=##40;:__ct__4TOBJ7POINTER;2A.;FUNC::50=##17;:4TOBJ;2A.;PROC::51=##39;:4TOBJ;2A*0;2;;DONE::52=##39;:__dt__4TOBJ7POINTER;2A*1;2;;;~%2;", desc=0, type=128, objfile=0x801568c8) at ../../../binutils-gdb/gdb/stabsread.c:1316
#6  0x005abfa6 in process_one_symbol (type=128, desc=0, valu=0,
    name=0x8018ec27 ":Tt2=s8Z:/038,0,32;$vf2:48,32;INIT::49=##40;:__ct__4TOBJ7POINTER;2A.;FUNC::50=##17;:4TOBJ;2A.;PROC::51=##39;:4TOBJ;2A*0;2;;DONE::52=##39;:__dt__4TOBJ7POINTER;2A*1;2;;;~%2;",
    section_offsets=0x80189828, objfile=0x801568c8) at ../../../binutils-gdb/gdb/dbxread.c:3203
#7  0x005aaee9 in read_ofile_symtab (objfile=0x801568c8, pst=0x80190148) at ../../../binutils-gdb/gdb/dbxread.c:2601
#8  0x005aa961 in dbx_psymtab_to_symtab_1 (objfile=0x801568c8, pst=0x80190148) at ../../../binutils-gdb/gdb/dbxread.c:2418
#9  0x005aaa98 in dbx_read_symtab (self=0x80190148, objfile=0x801568c8) at ../../../binutils-gdb/gdb/dbxread.c:2471
#10 0x0051fa46 in psymtab_to_symtab (objfile=0x801568c8, pst=0x80190148) at ../../../binutils-gdb/gdb/psymtab.c:788
#11 0x0051f2d3 in psym_lookup_symbol (objfile=0x801568c8, block_index=0, name=0x8014b4f8 "main", domain=VAR_DOMAIN) at ../../../binutils-gdb/gdb/psymtab.c:520
#12 0x00518140 in lookup_symbol_via_quick_fns (objfile=0x801568c8, block_index=0, name=0x8014b4f8 "main", domain=VAR_DOMAIN) at ../../../binutils-gdb/gdb/symtab.c:2436
#13 0x00518488 in lookup_symbol_in_objfile (objfile=0x801568c8, block_index=0, name=0x8014b4f8 "main", domain=VAR_DOMAIN) at ../../../binutils-gdb/gdb/symtab.c:2604
#14 0x0051865f in lookup_symbol_global_iterator_cb (objfile=0x801568c8, cb_data=0x2c2a878) at ../../../binutils-gdb/gdb/symtab.c:2685
#15 0x0041bda5 in windows_iterate_over_objfiles_in_search_order (gdbarch=0x80149d10, cb=0x5185ef <lookup_symbol_global_iterator_cb>, cb_data=0x2c2a878, current_objfile=0x0)
    at ../../../binutils-gdb/gdb/windows-tdep.c:452
#16 0x0056c548 in gdbarch_iterate_over_objfiles_in_search_order (gdbarch=0x80149d10, cb=0x5185ef <lookup_symbol_global_iterator_cb>, cb_data=0x2c2a878, current_objfile=0x0)
    at ../../../binutils-gdb/gdb/gdbarch.c:4412
#17 0x00518777 in lookup_global_symbol (name=0x8014b4f8 "main", block=0x0, domain=VAR_DOMAIN) at ../../../binutils-gdb/gdb/symtab.c:2730
#18 0x005182b6 in basic_lookup_symbol_nonlocal (langdef=0x81be80 <c_language_defn>, name=0x8014b4f8 "main", block=0x0, domain=VAR_DOMAIN) at ../../../binutils-gdb/gdb/symtab.c:2530
#19 0x00517a76 in lookup_symbol_aux (name=0x8014b4f8 "main", block=0x0, domain=VAR_DOMAIN, language=language_c, is_a_field_of_this=0x0) at ../../../binutils-gdb/gdb/symtab.c:2148
#20 0x00517431 in lookup_symbol_in_language (name=0x8014b4f8 "main", block=0x0, domain=VAR_DOMAIN, lang=language_c, is_a_field_of_this=0x0) at ../../../binutils-gdb/gdb/symtab.c:1944
#21 0x00517476 in lookup_symbol (name=0x8014b4f8 "main", block=0x0, domain=VAR_DOMAIN, is_a_field_of_this=0x0) at ../../../binutils-gdb/gdb/symtab.c:1958
#22 0x00524c1e in set_initial_language () at ../../../binutils-gdb/gdb/symfile.c:1698
#23 0x005242ef in symbol_file_add_main_1 (args=0x2c2ac39 "/home/Pierre/pas/trunk/fpcsrc/ide/test.o", from_tty=1, flags=0) at ../../../binutils-gdb/gdb/symfile.c:1327
#24 0x00524290 in symbol_file_add_main (args=0x2c2ac39 "/home/Pierre/pas/trunk/fpcsrc/ide/test.o", from_tty=1) at ../../../binutils-gdb/gdb/symfile.c:1311
#25 0x005569e5 in catch_command_errors_const (command=0x524270 <symbol_file_add_main>, arg=0x2c2ac39 "/home/Pierre/pas/trunk/fpcsrc/ide/test.o", from_tty=1, mask=RETURN_MASK_ALL)
    at ../../../binutils-gdb/gdb/main.c:396
#26 0x005578b6 in captured_main (data=0x2c2abb4) at ../../../binutils-gdb/gdb/main.c:1042
#27 0x00552b9d in catch_errors (func=0x556c36 <captured_main>, func_args=0x2c2abb4, errstring=0x7ea741 <__PRETTY_FUNCTION__.13998+168> "", mask=RETURN_MASK_ALL)
    at ../../../binutils-gdb/gdb/exceptions.c:237
#28 0x00557c4b in gdb_main (args=0x2c2abb4) at ../../../binutils-gdb/gdb/main.c:1157
#29 0x0040120c in main (
During symbol reading, incomplete CFI data; DW_CFA_restore unspecified
register ebx (#3) at 0x6100776e.
argc=2, argv=0x2c2abec) at ../../../binutils-gdb/gdb/gdb.c:32
(top-gdb) f 4
#4  0x005e1f34 in read_type (pp=0x2c2a4c0, objfile=0x801568c8) at ../../../binutils-gdb/gdb/stabsread.c:2006
2006            type = read_struct_type (pp, type, type_code, objfile);
(top-gdb) p pp
$1 = (char **) 0x2c2a4c0
(top-gdb) p *pp
$2 = 0x8018ec54 "__ct__4TOBJ7POINTER;2A.;FUNC::50=##17;:4TOBJ;2A.;PROC::51=##39;:4TOBJ;2A*0;2;;DONE::52=##39;:__dt__4TOBJ7POINTER;2A*1;2;;;~%2;"
(top-gdb) f 3
#3  0x005e578a in read_struct_type (pp=0x2c2a4c0, type=0x801a7f88, type_code=TYPE_CODE_STRUCT, objfile=0x801568c8) at ../../../binutils-gdb/gdb/stabsread.c:3555
3555          || !read_member_functions (&fi, pp, type, objfile)
(top-gdb) p *type
$3 = {pointer_type = 0x0, reference_type = 0x0, chain = 0x801a7f88, instance_flags = 0, length = 8, main_type = 0x801a7fa0}
(top-gdb) p *type.main_type
$4 = {code = TYPE_CODE_STRUCT, flag_unsigned = 0, flag_nosign = 0, flag_stub = 0, flag_target_stub = 0, flag_static = 0, flag_prototyped = 0, flag_incomplete = 0, flag_varargs = 0,
  flag_vector = 0, flag_stub_supported = 0, flag_gnu_ifunc = 0, flag_fixed_instance = 0, flag_objfile_owned = 1, flag_declared_class = 0, flag_flag_enum = 0,
  type_specific_field = TYPE_SPECIFIC_CPLUS_STUFF, nfields = 2, name = 0x0, tag_name = 0x0, owner = {objfile = 0x801568c8, gdbarch = 0x801568c8}, target_type = 0x0, flds_bnds = {
    fields = 0x801a7fd8, bounds = 0x801a7fd8}, type_specific = {cplus_stuff = 0x801a8008, gnat_stuff = 0x801a8008, floatformat = 0x801a8008, func_stuff = 0x801a8008, self_type = 0x801a8008},
  data_location = 0x0}
(top-gdb) f 2
#2  0x005e2d10 in read_member_functions (fip=0x2c2a354, pp=0x2c2a4c0, type=0x801a7f88, objfile=0x801568c8) at ../../../binutils-gdb/gdb/stabsread.c:2389
2389                  if (!TYPE_SELF_TYPE (new_sublist->fn_field.type))
(top-gdb) p new_sublist->fn_field.type
$5 = (struct type *) 0x801a8050
(top-gdb) p *new_sublist->fn_field.type
$6 = {pointer_type = 0x0, reference_type = 0x0, chain = 0x801a8050, instance_flags = 0, length = 1, main_type = 0x801a8068}
(top-gdb) p *new_sublist->fn_field.type.main_type
$7 = {code = TYPE_CODE_METHOD, flag_unsigned = 0, flag_nosign = 0, flag_stub = 1, flag_target_stub = 0, flag_static = 0, flag_prototyped = 0, flag_incomplete = 0, flag_varargs = 0,
  flag_vector = 0, flag_stub_supported = 0, flag_gnu_ifunc = 0, flag_fixed_instance = 0, flag_objfile_owned = 1, flag_declared_class = 0, flag_flag_enum = 0,
  type_specific_field = TYPE_SPECIFIC_NONE, nfields = 0, name = 0x0, tag_name = 0x0, owner = {objfile = 0x801568c8, gdbarch = 0x801568c8}, target_type = 0x80191708, flds_bnds = {fields = 0x0,
    bounds = 0x0}, type_specific = {cplus_stuff = 0x0, gnat_stuff = 0x0, floatformat = 0x0, func_stuff = 0x0, self_type = 0x0}, data_location = 0x0}
(top-gdb) f 1
#1  0x00570a5f in internal_type_self_type (type=0x801a8050) at ../../../binutils-gdb/gdb/gdbtypes.c:1204
1204          gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_FUNC);
(top-gdb) li internal_type_self_type
1191       TYPE must be one of TYPE_CODE_METHODPTR, TYPE_CODE_MEMBERPTR, or
1192       TYPE_CODE_METHOD.  */
1193
1194    struct type *
1195    internal_type_self_type (struct type *type)
1196    {
1197      switch (TYPE_CODE (type))
1198        {
1199        case TYPE_CODE_METHODPTR:
1200        case TYPE_CODE_MEMBERPTR:
(top-gdb)
1201          gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_SELF_TYPE);
1202          return TYPE_MAIN_TYPE (type)->type_specific.self_type;
1203        case TYPE_CODE_METHOD:
1204          gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_FUNC);
1205          return TYPE_MAIN_TYPE (type)->type_specific.func_stuff->self_type;
1206        default:
1207          gdb_assert_not_reached ("bad type");
1208        }
1209    }
1210
(top-gdb)


> -----Message d'origine-----
> De : gdb-patches-owner@sourceware.org [mailto:gdb-patches-
> owner@sourceware.org] De la part de Doug Evans
> Envoyà : vendredi 6 fÃvrier 2015 08:20
> Ã : Pierre Muller
> Cc : gdb-patches@sourceware.org
> Objet : Re: [PATCH 4/5] Remove struct
> main_type.vptr_{fieldno,basetype}: TYPE_SPECIFIC_SELF_TYPE
> 
> "Pierre Muller" <pierre.muller@ics-cnrs.unistra.fr> writes:
> >   Hi all,
> >
> >
> >> -----Message d'origine-----
> >> De : gdb-patches-owner@sourceware.org [mailto:gdb-patches-
> >> owner@sourceware.org] De la part de Doug Evans
> >> Envoyà : lundi 26 janvier 2015 01:07
> >> Ã : gdb-patches@sourceware.org; gaius@glam.ac.uk
> >> Objet : [PATCH 4/5] Remove struct main_type.vptr_{fieldno,basetype}:
> >> TYPE_SPECIFIC_SELF_TYPE
> >>
> >> Hi.
> >>
> >> This patch moves TYPE_SELF_TYPE into new field
> type_specific.self_type
> >> for MEMBERPTR,METHODPTR types, and into type_specific.func_stuff
> >> for METHODs, and then updates everything to use that.
> >> TYPE_CODE_METHOD could share some things with TYPE_CODE_FUNC
> >> (e.g. TYPE_NO_RETURN) and it seemed simplest to keep them together.
> >>
> >> Moving TYPE_SELF_TYPE into type_specific.func_stuff for
> >> TYPE_CODE_METHOD
> >> is also nice because when we allocate space for function types we
> >> assume
> >> they're TYPE_CODE_FUNCs. If TYPE_CODE_METHODs don't need or use that
> >> space then that space would be wasted, and cleaning that up would
> >> involve
> >> more invasive changes.
> >>
> >> In order to catch errant uses I've added accessor functions
> >> that do some checking.
> >>
> >> One can no longer assign to TYPE_SELF_TYPE like this:
> >>
> >>   TYPE_SELF_TYPE (foo) = bar;
> >>
> >> One instead has to do:
> >>
> >>   set_type_self_type (foo, bar);
> >>
> >> But I've left reading of the type to the macro:
> >>
> >>   bar = TYPE_SELF_TYPE (foo);
> >>
> >> I could add SET_TYPE_SELF_TYPE as a wrapper on set_type_self_type
> >> if you prefer that.
> >>
> >> In order to discourage bypassing the TYPE_SELF_TYPE macro
> >> I've named the underlying function that implements it
> > ....
> >> 	* stabsread.c (read_member_functions): Mark methods with
> >> 	TYPE_CODE_METHOD, not TYPE_CODE_FUNC.  Update setting of
> >> 	TYPE_SELF_TYPE.
> > .....
> >> diff --git a/gdb/stabsread.c b/gdb/stabsread.c
> >> index 1f46f75..423c442 100644
> >> --- a/gdb/stabsread.c
> >> +++ b/gdb/stabsread.c
> >> @@ -2376,14 +2376,21 @@ read_member_functions (struct field_info
> *fip,
> >> char **pp, struct type *type,
> >>  	      p++;
> >>  	    }
> >>
> >> -	  /* If this is just a stub, then we don't have the real name
> >> here.  */
> >> +	  /* These are methods, not functions.  */
> >> +	  if (TYPE_CODE (new_sublist->fn_field.type) == TYPE_CODE_FUNC)
> >> +	    TYPE_CODE (new_sublist->fn_field.type) = TYPE_CODE_METHOD;
> >> +	  else
> >> +	    gdb_assert (TYPE_CODE (new_sublist->fn_field.type)
> >> +			== TYPE_CODE_METHOD);
> >>
> >> +	  /* If this is just a stub, then we don't have the real name
> >> here.  */
> >>  	  if (TYPE_STUB (new_sublist->fn_field.type))
> >>  	    {
> >>  	      if (!TYPE_SELF_TYPE (new_sublist->fn_field.type))
> >   I suspect this is the part that generates the failure
> > I saw when trying to test my pascal patch that used stabs debugging
> > information.
> >
> >      internal_type_self_type  generates an internal error
> > it does not simply return NULL...
> 
> Hi.
> Is it easy/possible to send me a repro?
> Even just the binary that triggers the problem would help.
> It would be good to verify what's going on here.
> If internal_type_self_type got an internal error it must be this one:
> 
>       gdb_assert (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_FUNC);
> 
> But it's hard to see how that would fail given the earlier check
> for TYPE_CODE_FUNC:
> 
> 	  if (TYPE_CODE (new_sublist->fn_field.type) == TYPE_CODE_FUNC)
> 	    TYPE_CODE (new_sublist->fn_field.type) = TYPE_CODE_METHOD;
> 	  else
> 	    gdb_assert (TYPE_CODE (new_sublist->fn_field.type)
> 			== TYPE_CODE_METHOD);
> 
> I'm not sure how we'd get here with anything other than TYPE_CODE_FUNC
> but for robustness I added the assert for TYPE_CODE_METHOD.
> And if we've got a TYPE_CODE_FUNC then AFAICT that means we've called
> make_function_type which sets TYPE_SPECIFIC_FIELD (type) =
> TYPE_SPECIFIC_FUNC.
> Ergo IWBN to reproduce this and see the details.
> 
> I'm not saying there isn't a problem of course,
> just that I may need some help understanding it.
> 
> Also, why couldn't internal_type_self_type return NULL?
> 
> >> -		TYPE_SELF_TYPE (new_sublist->fn_field.type) = type;
> >> +		set_type_self_type (new_sublist->fn_field.type, type);
> >>  	      new_sublist->fn_field.is_stub = 1;
> >>  	    }
> >> +
> >>  	  new_sublist->fn_field.physname = savestring (*pp, p - *pp);
> >>  	  *pp = p + 1;
> >
> >   The patch below removes the internal error,
> > but I am not sure it is the correct fix...
> > Maybe set_type_self_type should be called unconditionally.
> >
> >   Likewise, the line:
> > valops.c:2547:    gdb_assert (TYPE_SELF_TYPE (fns_ptr[0].type) !=
> NULL);
> > is not compatible with your new internal_type_self_type as this
> > new function never returns NULL....
> >
> >
> > Pierre Muller
> >
> > $ git diff
> > diff --git a/gdb/stabsread.c b/gdb/stabsread.c
> > index 2a160c5..392fdb2 100644
> > --- a/gdb/stabsread.c
> > +++ b/gdb/stabsread.c
> > @@ -2386,7 +2386,7 @@ read_member_functions (struct field_info *fip,
> char
> > **pp, struct type *type,
> >           /* If this is just a stub, then we don't have the real name
> here.
> > */
> >           if (TYPE_STUB (new_sublist->fn_field.type))
> >             {
> > -             if (!TYPE_SELF_TYPE (new_sublist->fn_field.type))
> > +              if (TYPE_SPECIFIC_FIELD (new_sublist->fn_field.type)
> ==
> > TYPE_SPECIFIC_NONE)
> >                 set_type_self_type (new_sublist->fn_field.type,
> type);
> >               new_sublist->fn_field.is_stub = 1;
> >             }

Attachment: test.s
Description: Text document

Attachment: test.pas
Description: Binary data

Attachment: test1.pas
Description: Binary data

Attachment: test2.inc
Description: Text document

Attachment: test2.pas
Description: Binary data


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