rawhide's gdb segfaults, w/patch

Jim Meyering
2008-12-28T19:37:41Z

Hi,

I was looking at http://bugzilla.redhat.com/365111 and did this
on a rawhide x86_64 system:

$ printf '#include <stdio.h>\nint main(){printf("foo");return 0;}\n' > k.c
$ gdb -q a.out
(gdb) b printf
Breakpoint 1 at 0x4003a0
(gdb) r
Starting program: /t/a.out

Breakpoint 1, __printf (format=0x4005bc "foo") at printf.c:30
30 {
(gdb) b mmap64
Breakpoint 2 at 0x3f742e2ba0
(gdb) c
Continuing.

Breakpoint 2, 0x0000003f742e2ba0 in mmap64 () from /lib64/libc.so.6
(gdb) ret (void*)-1
foozsh: segmentation fault gdb a.out

Debugging the debugger suggests it's due to a NULL dereference:
you can't apply SYMBOL_TYPE to a NULL pointer:

gdb/symtab.h:#define SYMBOL_TYPE(symbol) (symbol)->type

$ gdb -q --args gdb -q a.out
(gdb) r Starting program: /usr/bin/gdb -q a.out
warning: the debug information found in "/usr/lib/debug//lib64/libselinux.so.1.debug" does not match "/lib64/libselinux.so.1" (CRC mismatch).

warning: the debug information found in "/usr/lib/debug/lib64/libselinux.so.1.debug" does not match "/lib64/libselinux.so.1" (CRC mismatch).

[Thread debugging using libthread_db enabled]
(gdb) b printf
Breakpoint 1 at 0x4003a0
(gdb) r
Starting program: /t/a.out
Detaching after fork from child process 4853.
Detaching after fork from child process 4854.

Breakpoint 1, __printf (format=0x4005bc "foo") at printf.c:30
30 {
(gdb) b mmap64
Breakpoint 2 at 0x3f742e2ba0
(gdb) c
Continuing.

Breakpoint 2, 0x0000003f742e2ba0 in mmap64 () from /lib64/libc.so.6
(gdb) ret (void*)-1

Program received signal SIGSEGV, Segmentation fault.
return_command (retval_exp=0xbe8644 "(void*)-1", from_tty=1)
at ../../gdb/stack.c:1878
1878 else if (using_struct_return (SYMBOL_TYPE (thisfun), return_type))
(gdb) bt
#0 return_command (retval_exp=0xbe8644 "(void*)-1", from_tty=1)
at ../../gdb/stack.c:1878
#1 0x0000000000448daa in execute_command (p=0xbe864c "1", from_tty=1)
at ../../gdb/top.c:457
#2 0x00000000004feeb7 in command_handler (command=0xbe8640 "ret (void*)-1")
at ../../gdb/event-top.c:519
#3 0x00000000004ffbac in command_line_handler (rl=<value optimized out>)
at ../../gdb/event-top.c:744
#4 0x0000003248e27e7e in rl_callback_read_char () at ../callback.c:205
#5 0x00000000004ff009 in rl_callback_read_char_wrapper (client_data=0xcd9d40)
at ../../gdb/event-top.c:179
#6 0x00000000004fd8a8 in process_event () at ../../gdb/event-loop.c:394
#7 0x00000000004feb3b in gdb_do_one_event (data=<value optimized out>)
at ../../gdb/event-loop.c:459
#8 0x00000000004f8af4 in catch_errors (func=0x4fe8b0 <gdb_do_one_event>,
func_args=0x0, errstring=0x66750c "", mask=<value optimized out>)
at ../../gdb/exceptions.c:516
#9 0x0000000000497e78 in tui_command_loop (data=<value optimized out>)
at ../../gdb/tui/tui-interp.c:156
#10 0x00000000004412c9 in captured_command_loop (data=0xcd9d40)
at ../../gdb/main.c:99
#11 0x00000000004f8af4 in catch_errors (func=0x4412c0 <captured_command_loop>,
func_args=0x0, errstring=0x66750c "", mask=<value optimized out>)
at ../../gdb/exceptions.c:516
#12 0x0000000000441dee in captured_main (data=<value optimized out>)
at ../../gdb/main.c:838
#13 0x00000000004f8af4 in catch_errors (func=0x441300 <captured_main>,
func_args=0x7fffffffe490, errstring=0x66750c "", mask=<value optimized out>)
at ../../gdb/exceptions.c:516
#14 0x00000000004412b4 in gdb_main (args=<value optimized out>)
at ../../gdb/main.c:847
#15 0x0000000000441282 in main (argc=<value optimized out>, argv=0x4)
at ../../gdb/gdb.c:47
(gdb) p thisfun
$1 = (struct symbol *) 0x0
(gdb) p return_type
$2 = (struct type *) 0xc81f20

Here's an untested and quite possibly-wrong patch.
I.e., if the warning should be given even when "thisfun" is NULL,
it would have to be different.

From f092f666efa15a6451c8549f7cdc5f791ae838ed Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering@redhat.com>
Date: Sun, 28 Dec 2008 18:03:39 +0100
Subject: [PATCH] avoid NULL dereference

* stack.c (return_command): Guard use of SYMBOL_TYPE (thisfun).
---
gdb/ChangeLog | 5 +++++
gdb/stack.c | 3 ++-
2 files changed, 7 insertions(+), 1 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index aa64ed3..4eac798 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2008-12-28 Jim Meyering <meyering@redhat.com>
+
+ avoid NULL dereference
+ * stack.c (return_command): Guard use of SYMBOL_TYPE (thisfun).
+
2008-12-28 Pedro Alves <pedro@codesourcery.com>

* linux-fork.c (linux_fork_detach): New.
diff --git a/gdb/stack.c b/gdb/stack.c
index 51dd1bc..7ff58b1 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1823,7 +1823,8 @@ return_command (char *retval_exp, int from_tty)
is discarded, side effects such as "return i++" still
occur. */
return_value = NULL;
- else if (using_struct_return (SYMBOL_TYPE (thisfun), return_type))
+ else if (thisfun != NULL
+ && using_struct_return (SYMBOL_TYPE (thisfun), return_type))
{
query_prefix = "\
The location at which to store the function's return value is unknown.\n\
--
1.6.1.302.gccd4d