Bug 22854 - win64: crash inside call_function_by_hand()
Summary: win64: crash inside call_function_by_hand()
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: win32 (show other bugs)
Version: 8.1
: P2 normal
Target Milestone: 8.2
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 23472 23924 26304 (view as bug list)
Depends on:
Blocks:
 
Reported: 2018-02-16 12:45 UTC by Hannes Domani
Modified: 2024-01-09 16:17 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Hannes Domani 2018-02-16 12:45:50 UTC
Test file:
> int fun(void)
> {
>   return 5;
> }
> 
> int main(void)
> {
>   return fun() != 5;
> }
Compiled like this:
> $ gcc -O0 -g -ogdb-fun.exe gdb-fun.c
In gdb:
> $ gdb -q gdb-fun.exe
> Reading symbols from gdb-fun.exe...done.
> (gdb) b main
> Breakpoint 1 at 0x401618: file gdb-fun.c, line 9.
> (gdb) r
> Starting program: C:\src\tests\gdb-fun.exe
> [New Thread 2148.0x19a4]
> 
> Breakpoint 1, main () at gdb-fun.c:9
> 8         return fun() != 5;
> (gdb) p fun()
gdb crash:
> (gdb) r
> Starting program: C:\gcc\build64\gdb\gdb\gdb.exe gdb-fun.exe
> [New Thread 6212.0xe54]
> [New Thread 6212.0x764]
> gdb: Target exception EXCEPTION_ACCESS_VIOLATION at 0x7feff4f1197
>      read access violation at 0x78d15e0e
> 
> Thread 1 received signal SIGSEGV, Segmentation fault.
> 0x000007feff4f1197 in msvcrt!memmove () from C:\Windows\system32\msvcrt.dll
> (gdb) bt
> #0  0x000007feff4f1197 in msvcrt!memmove () from C:\Windows\system32\msvcrt.dll
> #1  0x00000000005c94c1 in regcache::raw_supply (this=0xb87b330, regnum=152, buf=0x78d15e0e) at C:/gcc/src/gdb-8.1/gdb/regcache.c:1024
> #2  0x0000000000421afd in do_windows_fetch_inferior_registers (regcache=0xb87b330, th=0xa623d70, r=152) at C:/gcc/src/gdb-8.1/gdb/windows-nat.c:531
> #3  0x0000000000421c21 in windows_fetch_inferior_registers (ops=<optimized out>, regcache=0xb87b330, r=152) at C:/gcc/src/gdb-8.1/gdb/windows-nat.c:549
> #4  0x000000000061faee in target_fetch_registers (regcache=regcache@entry=0xb87b330, regno=regno@entry=152) at C:/gcc/src/gdb-8.1/gdb/target.c:3439
> #5  0x00000000005c8868 in regcache::raw_update (this=0xb87b330, regnum=<optimized out>) at C:/gcc/src/gdb-8.1/gdb/regcache.c:554
> #6  0x00000000005c88dc in regcache::raw_read (this=0xb87b330, regnum=152, buf=0xab0e908 "") at C:/gcc/src/gdb-8.1/gdb/regcache.c:574
> #7  0x00000000005c80bb in regcache::save (this=this@entry=0xa623a20, cooked_read=cooked_read@entry=0x5c8b50 <do_cooked_read(void*, int, gdb_byte*)>,
>     src=src@entry=0xb87b330) at C:/gcc/src/gdb-8.1/gdb/regcache.c:305
> #8  0x00000000005c8198 in regcache::regcache (this=0xa623a20, src=...) at C:/gcc/src/gdb-8.1/gdb/regcache.c:217
> #9  0x00000000005c8213 in regcache_dup (src=src@entry=0xb87b330) at C:/gcc/src/gdb-8.1/gdb/regcache.c:355
> #10 0x000000000056f59a in save_infcall_suspend_state () at C:/gcc/src/gdb-8.1/gdb/infrun.c:8868
> #11 0x0000000000561f91 in call_function_by_hand_dummy (function=0xb861910, default_return_type=0x0, nargs=0, args=0x8aaf3d8, dummy_dtor=dummy_dtor@entry=0x0,
>     dummy_dtor_data=dummy_dtor_data@entry=0x0) at C:/gcc/src/gdb-8.1/gdb/infcall.c:773
> #12 0x00000000005635cb in call_function_by_hand (function=<optimized out>, default_return_type=<optimized out>, nargs=<optimized out>, args=<optimized out>)
>     at C:/gcc/src/gdb-8.1/gdb/infcall.c:695
> #13 0x00000000005323f6 in evaluate_funcall (expect_type=<optimized out>, expect_type@entry=0x0, exp=exp@entry=0xb8daf10, pos=pos@entry=0x8aaf7cc,
>     noside=EVAL_NORMAL) at C:/gcc/src/gdb-8.1/gdb/eval.c:1238
> #14 0x000000000053324f in evaluate_subexp_standard (expect_type=expect_type@entry=0x0, exp=0xb8daf10, pos=0x8aaf7cc, noside=noside@entry=EVAL_NORMAL)
>     at C:/gcc/src/gdb-8.1/gdb/eval.c:1893
> #15 0x00000000004ce207 in evaluate_subexp_c (expect_type=0x0, exp=0xb8daf10, pos=0x8aaf7cc, noside=EVAL_NORMAL) at C:/gcc/src/gdb-8.1/gdb/c-lang.c:706
> #16 0x000000000053118e in evaluate_expression (exp=<optimized out>) at C:/gcc/src/gdb-8.1/gdb/eval.c:148
> #17 0x00000000005b0dc4 in print_command_1 (exp=<optimized out>, voidprint=1) at C:/gcc/src/gdb-8.1/gdb/printcmd.c:1206
> #18 0x000000000042b9c2 in cmd_func (cmd=0xa6237e8, args=0x6e6f2626 <error: Cannot access memory at address 0x6e6f2626>, from_tty=8)
>     at C:/gcc/src/gdb-8.1/gdb/cli/cli-decode.c:1886
> #19 0x000000000062d8df in execute_command (p=<optimized out>, p@entry=0x386e50 "p fun()", from_tty=1) at C:/gcc/src/gdb-8.1/gdb/top.c:630
> #20 0x00000000005384cb in command_handler (command=0x386e50 "p fun()") at C:/gcc/src/gdb-8.1/gdb/event-top.c:583
> #21 0x000000000053881f in command_line_handler (rl=<optimized out>) at C:/gcc/src/gdb-8.1/gdb/event-top.c:774
> #22 0x0000000000537954 in gdb_rl_callback_handler (rl=0xa5f49f0 "") at C:/gcc/src/gdb-8.1/gdb/event-top.c:213
> #23 0x00000000006778a2 in rl_callback_read_char () at C:/gcc/src/gdb-8.1/readline/callback.c:220
> #24 0x00000000005378ae in gdb_rl_callback_read_char_wrapper_noexcept () at C:/gcc/src/gdb-8.1/gdb/event-top.c:175
> #25 0x0000000000537902 in gdb_rl_callback_read_char_wrapper (client_data=<optimized out>) at C:/gcc/src/gdb-8.1/gdb/event-top.c:192
> #26 0x0000000000537c41 in stdin_event_handler (error=<optimized out>, client_data=0x386e90) at C:/gcc/src/gdb-8.1/gdb/event-top.c:511
> #27 0x0000000000536bf1 in handle_file_event (ready_mask=2, file_ptr=0xaa5dd50) at C:/gcc/src/gdb-8.1/gdb/event-loop.c:733
> #28 gdb_wait_for_event (block=1) at C:/gcc/src/gdb-8.1/gdb/event-loop.c:884
> #29 gdb_do_one_event () at C:/gcc/src/gdb-8.1/gdb/event-loop.c:347
> #30 0x0000000000536d86 in gdb_do_one_event () at C:/gcc/src/gdb-8.1/gdb/event-loop.c:304
> #31 start_event_loop () at C:/gcc/src/gdb-8.1/gdb/event-loop.c:371
> #32 0x000000000058d91f in captured_command_loop () at C:/gcc/src/gdb-8.1/gdb/main.c:333
> #33 0x000000000058e85f in captured_main (data=0x8aafdc0) at C:/gcc/src/gdb-8.1/gdb/main.c:1160
> #34 gdb_main (args=args@entry=0x8aafe20) at C:/gcc/src/gdb-8.1/gdb/main.c:1176
> #35 0x00000000007d2827 in main (argc=2, argv=0x384600) at C:/gcc/src/gdb-8.1/gdb/gdb.c:32
So I compared the behavior with 8.0.1, and it differs because in 8.1 gdbarch_register_reggroup_p(gdbarch,152,save_reggroup) now returns 1:
> (gdb) up
> #1  0x00000000005c94c1 in regcache::raw_supply (this=0xb87b330, regnum=152, buf=0x78d15e0e) at C:/gcc/src/gdb-8.1/gdb/regcache.c:1024
> 1024          memcpy (regbuf, buf, size);
> (gdb)
> #2  0x0000000000421afd in do_windows_fetch_inferior_registers (regcache=0xb87b330, th=0xa623d70, r=152) at C:/gcc/src/gdb-8.1/gdb/windows-nat.c:531
> 531         regcache_raw_supply (regcache, r, context_offset);
> (gdb)
> #3  0x0000000000421c21 in windows_fetch_inferior_registers (ops=<optimized out>, regcache=0xb87b330, r=152) at C:/gcc/src/gdb-8.1/gdb/windows-nat.c:549
> 549         do_windows_fetch_inferior_registers (regcache, th, r);
> (gdb)
> #4  0x000000000061faee in target_fetch_registers (regcache=regcache@entry=0xb87b330, regno=regno@entry=152) at C:/gcc/src/gdb-8.1/gdb/target.c:3439
> 3439      current_target.to_fetch_registers (&current_target, regcache, regno);
> (gdb)
> #5  0x00000000005c8868 in regcache::raw_update (this=0xb87b330, regnum=<optimized out>) at C:/gcc/src/gdb-8.1/gdb/regcache.c:554
> 554           target_fetch_registers (this, regnum);
> (gdb)
> #6  0x00000000005c88dc in regcache::raw_read (this=0xb87b330, regnum=152, buf=0xab0e908 "") at C:/gcc/src/gdb-8.1/gdb/regcache.c:574
> 574       raw_update (regnum);
> (gdb)
> #7  0x00000000005c80bb in regcache::save (this=this@entry=0xa623a20, cooked_read=cooked_read@entry=0x5c8b50 <do_cooked_read(void*, int, gdb_byte*)>,
>     src=src@entry=0xb87b330) at C:/gcc/src/gdb-8.1/gdb/regcache.c:305
> 305               enum register_status status = cooked_read (src, regnum, dst_buf);
> (gdb) p gdbarch_register_reggroup_p(gdbarch,152,save_reggroup)
> $1 = 1
Looking closer its because tdesc_register_name(gdbarch,152) finds register 152:
> (gdb) p tdesc_register_name(gdbarch,152)
> $2 = 0xa5fff78 "fs_base"
In gdb/arch/amd64.c is this:
>   regnum = create_feature_i386_64bit_segments (tdesc, regnum);
gdb/features/i386/64bit-segments.c contains:
> static int
> create_feature_i386_64bit_segments (struct target_desc *result, long regnum)
> {
>   struct tdesc_feature *feature;
> 
>   feature = tdesc_create_feature (result, "org.gnu.gdb.i386.segments", "64bit-segments.xml");
>   tdesc_create_reg (feature, "fs_base", regnum++, 1, NULL, 64, "int");
>   tdesc_create_reg (feature, "gs_base", regnum++, 1, NULL, 64, "int");
>   return regnum;
> }
All of which wasn't done in 8.0.1 for win64.
So I just moved the create_feature_i386_64bit_segments() call into the if (is_linux) just above, and the crash is gone.
Comment 2 Hannes Domani 2020-04-01 19:10:36 UTC
*** Bug 23472 has been marked as a duplicate of this bug. ***
Comment 3 Hannes Domani 2020-08-01 11:35:47 UTC
*** Bug 26304 has been marked as a duplicate of this bug. ***
Comment 4 Hannes Domani 2024-01-09 16:17:20 UTC
*** Bug 23924 has been marked as a duplicate of this bug. ***