GDB up to and including 7.5.1 are NOT affected GDB 7.6.0 was not tested GDB 7.6.1 (from mingw / tested on w32 vista) has the below issue Consider the following program (compiled with free pascal / dwarf2) program Test_Record_var_param; type TFoo = record a,b: Integer; end; PFoo = ^TFoo; var r1, r2: TFoo; p1, p2: PFoo; begin P1 := @r1; P2 := @r1; end. ----- "p1" and "p2" are both pointers to the record declaration. Except for the name, they point to the same dwarf information entry in .debug_info Yet running gdb -i mi -gdb-set language pascal ptype p1^ &"ptype p1^\n" ~"type = TFOO = record \n" ~" A : LONGINT;\n" ~" B : LONGINT;\n" ~"end\n" ^done (gdb) -data-evaluate-expression p1^ ^done,value="{A = 0, B = 0}" (gdb) ptype p2^ &"ptype p2^\n" ~"type = TFOO = class \n" ~" public\n"" ~" A : LONGINT;\n" ~" B : LONGINT;\n" ~"end\n" ^done (gdb) -data-evaluate-expression p2^ ^done,value="{A = 0, B = 0}" (gdb) ptype p2^ claims p2 points to a class, which is incorrect. This only happens if "ptype p1^" wal run first. Running ptype p2^ ptype p1^ and ptype p1^ will claim to be a class. -data-evaluate-expression correctly returns a record in all cases (a rlass would include the class name) --- Extract from objdump <1><9d>: Abbrev Number: 2 (DW_TAG_variable) <9e> DW_AT_name : P1 <a1> DW_AT_location : 5 byte block: 3 10 e0 40 0 (DW_OP_addr: 40e010) <a7> DW_AT_type : <0xf6> <1><ab>: Abbrev Number: 2 (DW_TAG_variable) <ac> DW_AT_name : P2 <af> DW_AT_location : 5 byte block: 3 20 e0 40 0 (DW_OP_addr: 40e020) <b5> DW_AT_type : <0xf6> Both DW_AT_type point to the same entry <1><cb>: Abbrev Number: 4 (DW_TAG_typedef) <cc> DW_AT_name : TFOO <d1> DW_AT_type : <0xd5> <1><d5>: Abbrev Number: 5 (DW_TAG_structure_type) <d6> DW_AT_name : TFOO <db> DW_AT_byte_size : 8 <2><dc>: Abbrev Number: 6 (DW_TAG_member) <dd> DW_AT_name : A <df> DW_AT_data_member_location: 2 byte block: 23 0 (DW_OP_plus_uconst: 0) <e2> DW_AT_type : <0x10a> <2><e6>: Abbrev Number: 6 (DW_TAG_member) <e7> DW_AT_name : B <e9> DW_AT_data_member_location: 2 byte block: 23 4 (DW_OP_plus_uconst: 4) <ec> DW_AT_type : <0x10a> <1><f6>: Abbrev Number: 4 (DW_TAG_typedef) <f7> DW_AT_name : PFOO <fc> DW_AT_type : <0x100> <1><100>: Abbrev Number: 8 (DW_TAG_pointer_type) <101> DW_AT_type : <0xcb> <1><10a>: Abbrev Number: 4 (DW_TAG_typedef) <10b> DW_AT_name : LONGINT <113> DW_AT_type : <0x117> <1><117>: Abbrev Number: 9 (DW_TAG_base_type) <118> DW_AT_name : LONGINT <120> DW_AT_encoding : 5 (signed) <121> DW_AT_byte_size : 4
FWIW, I have tested this using CVS HEAD on Fedora 17 x86_64 with FPC version 2.6.0, and could not reproduce the bug. (gdb) -gdb-set language pascal ^done (gdb) ptype p1^ &"ptype p1^\n" ~"type = TFOO = record \n" ~" A : SMALLINT;\n" ~" B : SMALLINT;\n" ~"end\n" ^done (gdb) ptype p2^ &"ptype p2^\n" ~"type = TFOO = record \n" ~" A : SMALLINT;\n" ~" B : SMALLINT;\n" ~"end\n" ^done Would it be possible to give it a try using CVS HEAD? Thanks.
Closing as OBSOLETE due to inactivity. Feel free to reopen if still valid.
I finally got to build 7.8.1 under mingw 32 bit windows. The issue still exists. I only tested on Windows. Compile the program. gdb_781.exe -i mi project1.exe b project1.lpr:10 r ptype p1^ -data-evaluate-expression p1^ ptype p2^ The last ptype shows "class", but it should be record
Just reconfirming, still present in gdb 7.10
I can confirm this is still present in gdb 8.2.1-2+b3 in Debian Buster. (when using fpc 3.0.4+dfsg-22) As a workaround, one has to manually typecast, for example: (gdb) p tempplan^[curplan].cache Type PLANARRAY is not a structure or union type. (gdb) ptype tempplan^[curplan] type = PLANETTYPE = class public SYSTEM : BYTE; CACHE : array [1..7] of WORD; AGE : LONGINT; end (gdb) p PLANETTYPE(tempplan^[curplan]).cache $42 = {5000, 5100, 5140, 0, 5040, 0, 5020} (Note: PLANETTYPE is actually a RECORD, not CLASS): type planettype= record system: byte; cache: array[1..7] of word; age: longint; end; planarray= array[1..1000] of planettype; var tempplan: ^planarray;
Issue confirmed for gdb-7.6 also, the problem comes from a change of the type.main_type.type_specific.cplus_stuff field due to RTTI reading. This suggest that Free Pascal also issues RTTI information about 'record' not only 'classes', which is probably true, but this is a branch of Free Pascal compiler I do not know well... So if someone with more knowledge about that part can go further. It seems that: top> f 0 #0 0x005fbe0a in gnuv3_get_vtable (gdbarch=0x276e390, container_type=0x2792090, container_addr=4243472) at ../../gdb-7.6/gdb/gnu-v3-abi.c:249 249 if (!gnuv3_dynamic_class (check_typedef (container_type))) top> li 244 struct value *vtable_pointer; 245 CORE_ADDR vtable_address; 246 247 /* If this type does not have a virtual table, don't read the first 248 field. */ 249 if (!gnuv3_dynamic_class (check_typedef (container_type))) 250 return NULL; here the call to gnuv3_dynamic_class changes the cplus_stuff from cplus_struct_default to a new 'struct', even if there gnuv3_dynamic_class return false. I have no idea if this is expected behavior, but it does indeed explain why pty TFOO generates a different output after p p1^ has been issued! Pierre Muller (gdb) p p1^ Hardware watchpoint 3: *$3 Old value = (struct cplus_struct_type *) 0x7b07c0 <cplus_struct_default> New value = (struct cplus_struct_type *) 0x2792500 allocate_cplus_struct_type (type=0x2792090) at ../../gdb-7.6/gdb/gdbtypes.c:1932 1932 *(TYPE_RAW_CPLUS_SPECIFIC (type)) = cplus_struct_default; top> bt #0 allocate_cplus_struct_type (type=0x2792090) at ../../gdb-7.6/gdb/gdbtypes.c:1932 #1 0x005fbae0 in gnuv3_dynamic_class (type=0x2792090) at ../../gdb-7.6/gdb/gnu-v3-abi.c:206 #2 0x005fbe0a in gnuv3_get_vtable (gdbarch=0x276e390, container_type=0x2792090, container_addr=4243472) at ../../gdb-7.6/gdb/gnu-v3-abi.c:249 #3 0x005fbf37 in gnuv3_rtti_type (value=0x2795f68, full_p=0x1e7f5e4, top_p=0x1e7f5e0, using_enc_p=0x1e7f5dc) at ../../gdb-7.6/gdb/gnu-v3-abi.c:301 #4 0x005fdf21 in value_rtti_type (v=0x2795f68, full=0x1e7f5e4, top=0x1e7f5e0, using_enc=0x1e7f5dc) at ../../gdb-7.6/gdb/cp-abi.c:120 #5 0x004c619c in value_full_object (argp=0x2795f68, rtype=0x0, xfull=0, xtop=0, xusing_enc=0) at ../../gdb-7.6/gdb/valops.c:3604 #6 0x004b6e81 in readjust_indirect_value_type (value=0x2795f68, enc_type=0x2792090, original_type=0x2792148, original_value=0x4656798) at ../../gdb-7.6/gdb/value.c:3277 #7 0x004c28db in value_ind (arg1=0x4656798) at ../../gdb-7.6/gdb/valops.c:1776 #8 0x004bda86 in evaluate_subexp_standard (expect_type=0x0, exp=0x279d7e0, pos=0x1e7f99c, noside=EVAL_NORMAL) at ../../gdb-7.6/gdb/eval.c:2550 #9 0x004b71ee in evaluate_subexp (expect_type=0x0, exp=0x279d7e0, pos=0x1e7f99c, noside=EVAL_NORMAL) at ../../gdb-7.6/gdb/eval.c:71 #10 0x004b736d in evaluate_expression (exp=0x279d7e0) at ../../gdb-7.6/gdb/eval.c:146 #11 0x004d10fa in print_command_1 (exp=0x2866f02 "p1^", voidprint=1) at ../../gdb-7.6/gdb/printcmd.c:965 #12 0x004d123f in print_command (exp=0x2866f02 "p1^", from_tty=1) at ../../gdb-7.6/gdb/printcmd.c:1006 #13 0x00449a90 in do_cfunc (c=0x2745890, args=0x2866f02 "p1^", from_tty=1) at ../../gdb-7.6/gdb/cli/cli-decode.c:113 #14 0x0044c263 in cmd_func (cmd=0x2745890, args=0x2866f02 "p1^", from_tty=1) at ../../gdb-7.6/gdb/cli/cli-decode.c:1859 #15 0x005ebf00 in execute_command (p=0x2866f04 "^", from_tty=1) at ../../gdb-7.6/gdb/top.c:484 #16 0x00516a4b in command_handler (command=0x2866f00 "p p1^") at ../../gdb-7.6/gdb/event-top.c:431 #17 0x00516f47 in command_line_handler (rl=0x4587840 "") at ../../gdb-7.6/gdb/event-top.c:629 #18 0x0062885e in rl_callback_read_char () at ../../gdb-7.6/readline/callback.c:220 #19 0x005165ff in rl_callback_read_char_wrapper (client_data=0x0) at ../../gdb-7.6/gdb/event-top.c:163 #20 0x00516972 in stdin_event_handler (error=0, client_data=0x0) at ../../gdb-7.6/gdb/event-top.c:371 #21 0x00515bab in handle_file_event (data=...) at ../../gdb-7.6/gdb/event-loop.c:768 #22 0x005152c8 in process_event () at ../../gdb-7.6/gdb/event-loop.c:342 #23 0x0051538d in gdb_do_one_event () at ../../gdb-7.6/gdb/event-loop.c:406 #24 0x005153de in start_event_loop () at ../../gdb-7.6/gdb/event-loop.c:431 #25 0x00516628 in cli_command_loop () at ../../gdb-7.6/gdb/event-top.c:176 #26 0x0050de2d in current_interp_command_loop () at ../../gdb-7.6/gdb/interps.c:331 #27 0x0050ee3c in captured_command_loop (data=0x0) at ../../gdb-7.6/gdb/main.c:258 #28 0x0050ce7a in catch_errors (func=0x50ee27 <captured_command_loop>, func_args=0x0, errstring=0x7a6a04 <__PRETTY_FUNCTION__.12659+138> "", mask=6) at ../../gdb-7.6/gdb/exceptions.c:546 #29 0x00510060 in captured_main (data=0x1e7fe90) at ../../gdb-7.6/gdb/main.c:1041 #30 0x0050ce7a in catch_errors (func=0x50f087 <captured_main>, func_args=0x1e7fe90, errstring=0x7a6a04 <__PRETTY_FUNCTION__.12659+138> "", mask=6) at ../../gdb-7.6/gdb/exceptions.c:546 #31 0x00510096 in gdb_main (args=0x1e7fe90) at ../../gdb-7.6/gdb/main.c:1050 #32 0x004015b4 in main (argc=2, argv=0x2866710) at ../../gdb-7.6/gdb/gdb.c:34
I can reproduce this with gdb-8.3, but no longer with gdb-10.1 and up.