This is the mail archive of the gdb-patches@sources.redhat.com 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]

RFA: Patch for SIGSEGV in evaluate_subexp_standard


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)
     {


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