This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
RFA: Patch for SIGSEGV in evaluate_subexp_standard
- From: Fred Fish <fnf at fishpond dot ninemoons dot com>
- To: gdb-patches at sources dot redhat dot com
- Cc: fnf at redhat dot com
- Date: Mon, 10 Dec 2001 10:44:21 -0700 (MST)
- Subject: RFA: Patch for SIGSEGV in evaluate_subexp_standard
- Reply-to: fnf at redhat dot com
This example demonstrates a bug that is triggered when a C++ file is
not compiled with -g. Attached is a proposed patch to fix the
problem. I've regression tested the patch with the gdb testsuite and
there are no regressions on an i686-pc-linux-gnu host.
========================= Begin example =========================
Script started on Mon Dec 10 10:27:14 2001
$ cat Makefile
bug: bug1.o bug2.o bug3.o
/usr/bin/g++ -o bug bug1.o bug2.o bug3.o
bug1.o: bug.h bug1.cc
/usr/bin/g++ -g -I. -c -o $@ bug1.cc
bug2.o: bug.h bug2.cc
/usr/bin/g++ -I. -c -o $@ bug2.cc
bug3.o: bug.h bug3.cc
/usr/bin/g++ -g -I. -c -o $@ bug3.cc
clean:
rm -f *.o bug *~
$ cat bug.h
class MSSymbol
{
public:
const char *asString(void);
};
class MSString
{
public:
const char *asString();
};
$ cat bug1.cc
#include "bug.h"
const char *MSSymbol::asString(void)
{
return "mssymbol";
}
$ cat bug2.cc
#include "bug.h"
const char *MSString::asString(void)
{
return "msstring";
}
$ cat bug3.cc
#include <iostream.h>
#include "bug.h"
main()
{
MSSymbol x1;
MSString x2;
cout << x1.asString() << endl;
cout << x2.asString() << endl;
return 0;
}
$ make clean
rm -f *.o bug *~
$ make
/usr/bin/g++ -g -I. -c -o bug1.o bug1.cc
/usr/bin/g++ -I. -c -o bug2.o bug2.cc
/usr/bin/g++ -g -I. -c -o bug3.o bug3.cc
/usr/bin/g++ -o bug bug1.o bug2.o bug3.o
$ gdb -nw -nx bug
GNU gdb 2001-12-10-cvs
Copyright 2001 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) br main
Breakpoint 1 at 0x8048676: file bug3.cc, line 9.
(gdb) run
Starting program: /x1/links/build/sourceware/gdb/H-i686-pc-linux-gnu/T-i686-pc-linux-gnu/gdb/bug
Breakpoint 1, main () at bug3.cc:9
9 cout << x1.asString() << endl;
(gdb) ptype x1.asString()
type = char *
(gdb) ptype x2.asString()
Segmentation fault (core dumped)
$ gdb -nw gdb
GNU gdb 2001-12-10-cvs
Copyright 2001 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
Setting up the environment for debugging gdb.
Breakpoint 1 at 0x80ee992: file /src/sourceware/gdb/src/gdb/utils.c, line 757.
Breakpoint 2 at 0x8163b7e: file /src/sourceware/gdb/src/gdb/cli/cli-cmds.c, line 182.
(top-gdb) run -nw -nx bug
Starting program: /x1/links/build/sourceware/gdb/H-i686-pc-linux-gnu/T-i686-pc-linux-gnu/gdb/gdb -nw -nx bug
GNU gdb 2001-12-10-cvs
Copyright 2001 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) br main
Breakpoint 1 at 0x8048676: file bug3.cc, line 9.
(gdb) run
Starting program: /x1/links/build/sourceware/gdb/H-i686-pc-linux-gnu/T-i686-pc-linux-gnu/gdb/bug
Breakpoint 1, main () at bug3.cc:9
9 cout << x1.asString() << endl;
(gdb) ptype x2.asString()
Program received signal SIGSEGV, Segmentation fault.
0x08079937 in evaluate_subexp_standard (expect_type=0x0, exp=0x860d330, pos=0xbfffed04, noside=EVAL_AVOID_SIDE_EFFECTS) at /src/sourceware/gdb/src/gdb/eval.c:929
929 struct type *ftype =
(top-gdb) list
924 a function call. This is here because people often want to
925 call, eg, strcmp, which gdb doesn't know is a function. If
926 gdb isn't asked for it's opinion (ie. through "whatis"),
927 it won't offer it. */
928
929 struct type *ftype =
930 TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0]));
931
932 if (ftype)
933 return allocate_value (TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0])));
(top-gdb) p argvec[0]
$1 = (struct value *) 0x0
(top-gdb) bt
#0 0x08079937 in evaluate_subexp_standard (expect_type=0x0, exp=0x860d330, pos=0xbfffed04, noside=EVAL_AVOID_SIDE_EFFECTS) at /src/sourceware/gdb/src/gdb/eval.c:929
#1 0x0807760f in evaluate_subexp (expect_type=0x0, exp=0x860d330, pos=0xbfffed04, noside=EVAL_AVOID_SIDE_EFFECTS) at /src/sourceware/gdb/src/gdb/eval.c:69
#2 0x0807784d in evaluate_type (exp=0x860d330) at /src/sourceware/gdb/src/gdb/eval.c:168
#3 0x080e242c in whatis_exp (exp=0x827bf6e "x2.asString()", show=1) at /src/sourceware/gdb/src/gdb/typeprint.c:141
#4 0x080e26a3 in ptype_command (typename=0x827bf6e "x2.asString()", from_tty=1) at /src/sourceware/gdb/src/gdb/typeprint.c:243
#5 0x080ebedf in execute_command (p=0x827bf7a ")", from_tty=1) at /src/sourceware/gdb/src/gdb/top.c:706
#6 0x080a9e4d in command_handler (command=0x827bf68 "ptype x2.asString()") at /src/sourceware/gdb/src/gdb/event-top.c:512
#7 0x080aa6b1 in command_line_handler (rl=0x8378c30 "8ö\034@8ö\034@.asStrin\030") at /src/sourceware/gdb/src/gdb/event-top.c:808
#8 0x081d060d in rl_callback_read_char () at /src/sourceware/gdb/src/readline/callback.c:114
#9 0x080a946b in rl_callback_read_char_wrapper (client_data=0x0) at /src/sourceware/gdb/src/gdb/event-top.c:168
#10 0x080a9d01 in stdin_event_handler (error=0, client_data=0x0) at /src/sourceware/gdb/src/gdb/event-top.c:426
#11 0x081039e4 in handle_file_event (event_file_desc=0) at /src/sourceware/gdb/src/gdb/event-loop.c:714
#12 0x081032ca in process_event () at /src/sourceware/gdb/src/gdb/event-loop.c:335
#13 0x08103311 in gdb_do_one_event (data=0x0) at /src/sourceware/gdb/src/gdb/event-loop.c:372
#14 0x080ebaa0 in do_catch_errors (uiout=0x82983d8, data=0xbffff038) at /src/sourceware/gdb/src/gdb/top.c:491
#15 0x080eb93d in catcher (func=0x80eba84 <do_catch_errors>, func_uiout=0x82983d8, func_args=0xbffff038, func_val=0xbffff044, func_caught=0xbffff040,
errstring=0x8220d60 "", mask=6) at /src/sourceware/gdb/src/gdb/top.c:423
#16 0x080ebae3 in catch_errors (func=0x81032dc <gdb_do_one_event>, func_args=0x0, errstring=0x8220d60 "", mask=6) at /src/sourceware/gdb/src/gdb/top.c:503
#17 0x08103343 in start_event_loop () at /src/sourceware/gdb/src/gdb/event-loop.c:396
#18 0x080a95ae in cli_command_loop () at /src/sourceware/gdb/src/gdb/event-top.c:200
#19 0x08071d5f in captured_command_loop (data=0x0) at /src/sourceware/gdb/src/gdb/main.c:95
#20 0x080ebaa0 in do_catch_errors (uiout=0x82983d8, data=0xbffff1d8) at /src/sourceware/gdb/src/gdb/top.c:491
#21 0x080eb93d in catcher (func=0x80eba84 <do_catch_errors>, func_uiout=0x82983d8, func_args=0xbffff1d8, func_val=0xbffff1e4, func_caught=0xbffff1e0,
errstring=0x81f1da7 "", mask=6) at /src/sourceware/gdb/src/gdb/top.c:423
#22 0x080ebae3 in catch_errors (func=0x8071d40 <captured_command_loop>, func_args=0x0, errstring=0x81f1da7 "", mask=6) at /src/sourceware/gdb/src/gdb/top.c:503
#23 0x08072943 in captured_main (data=0xbffff4d0) at /src/sourceware/gdb/src/gdb/main.c:714
#24 0x080ebaa0 in do_catch_errors (uiout=0x825d9c0, data=0xbffff4a8) at /src/sourceware/gdb/src/gdb/top.c:491
#25 0x080eb93d in catcher (func=0x80eba84 <do_catch_errors>, func_uiout=0x825d9c0, func_args=0xbffff4a8, func_val=0xbffff4b4, func_caught=0xbffff4b0,
errstring=0x81f1da7 "", mask=6) at /src/sourceware/gdb/src/gdb/top.c:423
#26 0x080ebae3 in catch_errors (func=0x8071d98 <captured_main>, func_args=0xbffff4d0, errstring=0x81f1da7 "", mask=6) at /src/sourceware/gdb/src/gdb/top.c:503
#27 0x0807296f in main (argc=4, argv=0xbffff544) at /src/sourceware/gdb/src/gdb/main.c:725
#28 0x400b7507 in __libc_start_main (main=0x8072948 <main>, argc=4, ubp_av=0xbffff544, init=0x8071124 <_init>, fini=0x81f1c70 <_fini>, rtld_fini=0x4000dc14 <_dl_fini>,
stack_end=0xbffff53c) at ../sysdeps/generic/libc-start.c:129
(top-gdb) quit
The program is running. Exit anyway? (y or n) e y
$ exit
Script done on Mon Dec 10 10:29:27 2001
========================= End example =========================
Here is the patch that fixes the bug.
2001-12-10 Fred Fish <fnf@redhat.com>
* values.c (value_fn_field): Add physname variable. Use a minimal
symbol if we don't find a full symbol. Remove setting of the new
value's type since that was already done by allocate_value().
Remove obsolete commented out error call.
Index: values.c
===================================================================
RCS file: /cvs/src/src/gdb/values.c,v
retrieving revision 1.29
diff -u -p -r1.29 values.c
--- values.c 2001/11/30 17:47:51 1.29
+++ values.c 2001/12/10 16:31:56
@@ -954,28 +954,40 @@ value_field (register value_ptr arg1, re
/* Return a non-virtual function as a value.
F is the list of member functions which contains the desired method.
- J is an index into F which provides the desired method. */
+ J is an index into F which provides the desired method.
+ We only use the symbol for its address, so be happy with either a
+ full symbol or a minimal symbol.
+ */
+
value_ptr
value_fn_field (value_ptr *arg1p, struct fn_field *f, int j, struct type *type,
int offset)
{
register value_ptr v;
register struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);
+ char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
struct symbol *sym;
+ struct minimal_symbol *msym;
- sym = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j),
- 0, VAR_NAMESPACE, 0, NULL);
+ sym = lookup_symbol (physname, 0, VAR_NAMESPACE, 0, NULL);
if (!sym)
+ {
+ msym = lookup_minimal_symbol (physname, NULL, NULL);
+ }
+
+ if (!sym && !msym)
return NULL;
-/*
- error ("Internal error: could not find physical method named %s",
- TYPE_FN_FIELD_PHYSNAME (f, j));
- */
v = allocate_value (ftype);
- VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
- VALUE_TYPE (v) = ftype;
+ if (sym)
+ {
+ VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+ }
+ else
+ {
+ VALUE_ADDRESS (v) = SYMBOL_VALUE_ADDRESS (msym);
+ }
if (arg1p)
{