This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: RFA: Patch for SIGSEGV in evaluate_subexp_standard
- From: Jim Blandy <jimb at zwingli dot cygnus dot com>
- To: fnf at redhat dot com
- Cc: gdb-patches at sources dot redhat dot com
- Date: 10 Dec 2001 15:50:15 -0500
- Subject: Re: RFA: Patch for SIGSEGV in evaluate_subexp_standard
- References: <200112101744.fBAHiMe20084@fishpond.ninemoons.com>
Approved, if you address Daniel's suggestion somehow.
Fred Fish <fnf@ns1.ninemoons.com> writes:
>
> 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)
> {
>