From a1a0d9748466c84c988529cf9fa192822151d272 Mon Sep 17 00:00:00 2001 From: Peter Schauer Date: Fri, 10 Mar 1995 11:21:32 +0000 Subject: [PATCH] Fix problems with infinite recursion when printing a class that contains a static instance of the class. * cp-valprint.c (dont_print_vb_obstack): Renamed from dont_print_obstack, made static. (dont_print_statmem_obstack): New obstack, controls printing of static member classes. (_initialize_cp_valprint): Initialize it. (cp_print_static_field): New function, handles printing of static members. (cp_print_value_fields): New parameter dont_print_statmem to handle recursive printing of static member classes, use cp_print_static_field to handle printing of static members. * c-valprint.c (cp_print_value_fields): Update prototype and call to include additional dont_print_statmem parameter. * c-valprint.c, f-valprint.c (dont_print_obstack): Remove unused extern declaration. * alpha-tdep.c, findvar.c, infptrace.c: Include . * config/alpha/tm-alpha.h (FRAME_FIND_SAVED_REGS): Call alpha_find_saved_regs if fi->saved_regs is still NULL. * elfread.c (elf_symtab_read): Ensure that the filename field of a minsym is nonempty. Ignore solib trampoline symbols from the main symbol table, they might have a bogus value. * procfs.c (set_proc_siginfo), config/alpha/alpha-osf2.mh: Fix typos in comments. --- gdb/ChangeLog | 31 +++++++++++ gdb/alpha-tdep.c | 3 +- gdb/c-valprint.c | 8 ++- gdb/cp-valprint.c | 130 +++++++++++++++++++++++++++++++++++++--------- gdb/elfread.c | 23 ++++---- gdb/f-valprint.c | 4 +- gdb/findvar.c | 4 +- gdb/procfs.c | 2 +- 8 files changed, 158 insertions(+), 47 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b6b147e10a2..ed895596330 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,34 @@ +Fri Mar 10 02:49:40 1995 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) + + Fix problems with infinite recursion when printing a class + that contains a static instance of the class. + * cp-valprint.c (dont_print_vb_obstack): Renamed from + dont_print_obstack, made static. + (dont_print_statmem_obstack): New obstack, controls printing + of static member classes. + (_initialize_cp_valprint): Initialize it. + (cp_print_static_field): New function, handles printing of + static members. + (cp_print_value_fields): New parameter dont_print_statmem to + handle recursive printing of static member classes, use + cp_print_static_field to handle printing of static members. + * c-valprint.c (cp_print_value_fields): Update prototype and + call to include additional dont_print_statmem parameter. + * c-valprint.c, f-valprint.c (dont_print_obstack): Remove unused + extern declaration. + + * alpha-tdep.c, findvar.c, infptrace.c: Include . + + * config/alpha/tm-alpha.h (FRAME_FIND_SAVED_REGS): Call + alpha_find_saved_regs if fi->saved_regs is still NULL. + + * elfread.c (elf_symtab_read): Ensure that the filename field + of a minsym is nonempty. Ignore solib trampoline symbols from + the main symbol table, they might have a bogus value. + + * procfs.c (set_proc_siginfo), config/alpha/alpha-osf2.mh: + Fix typos in comments. + Thu Mar 9 17:19:47 1995 Jim Kingdon * mdebugread.c (parse_symbol, psymtab_to_symtab_1): Initialize diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index bce35811b09..81e1d76cd03 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -1,5 +1,5 @@ /* Target-dependent code for the ALPHA architecture, for GDB, the GNU Debugger. - Copyright 1993, 1994 Free Software Foundation, Inc. + Copyright 1993, 1994, 1995 Free Software Foundation, Inc. This file is part of GDB. @@ -27,6 +27,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "dis-asm.h" #include "symfile.h" #include "objfiles.h" +#include /* FIXME: Some of this code should perhaps be merged with mips-tdep.c. */ diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c index 5e5791b12aa..5c5012455d6 100644 --- a/gdb/c-valprint.c +++ b/gdb/c-valprint.c @@ -1,5 +1,5 @@ /* Support for printing C values for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994 + Copyright 1986, 1988, 1989, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. This file is part of GDB. @@ -39,7 +39,7 @@ cp_print_class_method PARAMS ((char *, struct type *, GDB_FILE *)); extern void cp_print_value_fields PARAMS ((struct type *, char *, GDB_FILE *, int, int, - enum val_prettyprint, struct type **)); + enum val_prettyprint, struct type **, int)); extern int cp_is_vtbl_ptr_type PARAMS ((struct type *)); @@ -61,8 +61,6 @@ cp_type_print_method_args PARAMS ((struct type **, char *, char *, int, /* END-FIXME */ -extern struct obstack dont_print_obstack; - /* Print data of type TYPE located at VALADDR (within GDB), which came from the inferior at address ADDRESS, onto stdio stream STREAM according to @@ -323,7 +321,7 @@ c_val_print (type, valaddr, address, stream, format, deref_ref, recurse, break; } cp_print_value_fields (type, valaddr, stream, format, recurse, pretty, - 0); + NULL, 0); break; case TYPE_CODE_ENUM: diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c index 594ed0f5c6d..a59943e05d6 100644 --- a/gdb/cp-valprint.c +++ b/gdb/cp-valprint.c @@ -1,5 +1,6 @@ /* Support for printing C++ values for GDB, the GNU debugger. - Copyright 1986, 1988, 1989, 1991 Free Software Foundation, Inc. + Copyright 1986, 1988, 1989, 1991, 1994, 1995 + Free Software Foundation, Inc. This file is part of GDB. @@ -32,7 +33,13 @@ int vtblprint; /* Controls printing of vtbl's */ int objectprint; /* Controls looking up an object's derived type using what we find in its vtables. */ static int static_field_print; /* Controls printing of static fields. */ -struct obstack dont_print_obstack; + +static struct obstack dont_print_vb_obstack; +static struct obstack dont_print_statmem_obstack; + +static void +cp_print_static_field PARAMS ((struct type *, value_ptr, GDB_FILE *, int, int, + enum val_prettyprint)); static void cplus_print_value PARAMS ((struct type *, char *, GDB_FILE *, int, int, @@ -50,8 +57,6 @@ extern void cp_type_print_method_args PARAMS ((struct type **, char *, char *, int, GDB_FILE *)); -extern struct obstack dont_print_obstack; - /* END-FIXME */ void @@ -209,16 +214,19 @@ cp_is_vtbl_member(type) void cp_print_value_fields (type, valaddr, stream, format, recurse, pretty, - dont_print) + dont_print_vb, dont_print_statmem) struct type *type; char *valaddr; GDB_FILE *stream; int format; int recurse; enum val_prettyprint pretty; - struct type **dont_print; + struct type **dont_print_vb; + int dont_print_statmem; { int i, len, n_baseclasses; + struct obstack tmp_obstack; + char *last_dont_print = obstack_next_free (&dont_print_statmem_obstack); check_stub_type (type); @@ -230,7 +238,7 @@ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty, duplicates of virtual baseclasses. */ if (n_baseclasses > 0) cplus_print_value (type, valaddr, stream, format, recurse+1, pretty, - dont_print); + dont_print_vb); if (!len && n_baseclasses == 1) fprintf_filtered (stream, ""); @@ -239,6 +247,15 @@ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty, extern int inspect_it; int fields_seen = 0; + if (dont_print_statmem == 0) + { + /* If we're at top level, carve out a completely fresh + chunk of the obstack and use that until this particular + invocation returns. */ + tmp_obstack = dont_print_statmem_obstack; + obstack_finish (&dont_print_statmem_obstack); + } + for (i = n_baseclasses; i < len; i++) { /* If requested, skip printing of static fields. */ @@ -336,10 +353,9 @@ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty, { v = value_at (TYPE_FIELD_TYPE (type, i), (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym)); - val_print (TYPE_FIELD_TYPE (type, i), - VALUE_CONTENTS_RAW (v), - VALUE_ADDRESS (v), - stream, format, 0, recurse + 1, pretty); + cp_print_static_field (TYPE_FIELD_TYPE (type, i), v, + stream, format, recurse + 1, + pretty); } } else @@ -352,6 +368,14 @@ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty, annotate_field_end (); } + if (dont_print_statmem == 0) + { + /* Free the space used to deal with the printing + of the members from top level. */ + obstack_free (&dont_print_statmem_obstack, last_dont_print); + dont_print_statmem_obstack = tmp_obstack; + } + if (pretty) { fprintf_filtered (stream, "\n"); @@ -365,28 +389,29 @@ cp_print_value_fields (type, valaddr, stream, format, recurse, pretty, baseclasses. */ static void -cplus_print_value (type, valaddr, stream, format, recurse, pretty, dont_print) +cplus_print_value (type, valaddr, stream, format, recurse, pretty, + dont_print_vb) struct type *type; char *valaddr; GDB_FILE *stream; int format; int recurse; enum val_prettyprint pretty; - struct type **dont_print; + struct type **dont_print_vb; { struct obstack tmp_obstack; struct type **last_dont_print - = (struct type **)obstack_next_free (&dont_print_obstack); + = (struct type **)obstack_next_free (&dont_print_vb_obstack); int i, n_baseclasses = TYPE_N_BASECLASSES (type); - if (dont_print == 0) + if (dont_print_vb == 0) { /* If we're at top level, carve out a completely fresh chunk of the obstack and use that until this particular invocation returns. */ - tmp_obstack = dont_print_obstack; + tmp_obstack = dont_print_vb_obstack; /* Bump up the high-water mark. Now alpha is omega. */ - obstack_finish (&dont_print_obstack); + obstack_finish (&dont_print_vb_obstack); } for (i = 0; i < n_baseclasses; i++) @@ -403,16 +428,16 @@ cplus_print_value (type, valaddr, stream, format, recurse, pretty, dont_print) if (BASETYPE_VIA_VIRTUAL (type, i)) { struct type **first_dont_print - = (struct type **)obstack_base (&dont_print_obstack); + = (struct type **)obstack_base (&dont_print_vb_obstack); - int j = (struct type **)obstack_next_free (&dont_print_obstack) + int j = (struct type **)obstack_next_free (&dont_print_vb_obstack) - first_dont_print; while (--j >= 0) if (TYPE_BASECLASS (type, i) == first_dont_print[j]) goto flush_it; - obstack_ptr_grow (&dont_print_obstack, TYPE_BASECLASS (type, i)); + obstack_ptr_grow (&dont_print_vb_obstack, TYPE_BASECLASS (type, i)); } /* Fix to use baseclass_offset instead. FIXME */ @@ -440,22 +465,74 @@ cplus_print_value (type, valaddr, stream, format, recurse, pretty, dont_print) else cp_print_value_fields (TYPE_BASECLASS (type, i), baddr, stream, format, recurse, pretty, - (struct type **) obstack_base (&dont_print_obstack)); + (struct type **) obstack_base (&dont_print_vb_obstack), + 0); fputs_filtered (", ", stream); flush_it: ; } - if (dont_print == 0) + if (dont_print_vb == 0) { /* Free the space used to deal with the printing of this type from top level. */ - obstack_free (&dont_print_obstack, last_dont_print); + obstack_free (&dont_print_vb_obstack, last_dont_print); /* Reset watermark so that we can continue protecting ourselves from whatever we were protecting ourselves. */ - dont_print_obstack = tmp_obstack; + dont_print_vb_obstack = tmp_obstack; + } +} + +/* Print value of a static member. + To avoid infinite recursion when printing a class that contains + a static instance of the class, we keep the addresses of all printed + static member classes in an obstack and refuse to print them more + than once. + + VAL contains the value to print, TYPE, STREAM, RECURSE, and PRETTY + have the same meanings as in c_val_print. */ + +static void +cp_print_static_field (type, val, stream, format, recurse, pretty) + struct type *type; + value_ptr val; + GDB_FILE *stream; + int format; + int recurse; + enum val_prettyprint pretty; +{ + if (TYPE_CODE (type) == TYPE_CODE_STRUCT) + { + CORE_ADDR *first_dont_print; + int i; + + first_dont_print + = (CORE_ADDR *)obstack_base (&dont_print_statmem_obstack); + i = (CORE_ADDR *)obstack_next_free (&dont_print_statmem_obstack) + - first_dont_print; + + while (--i >= 0) + { + if (VALUE_ADDRESS (val) == first_dont_print[i]) + { + fputs_filtered ("", + stream); + return; + } + } + + obstack_grow (&dont_print_statmem_obstack, &VALUE_ADDRESS (val), + sizeof (CORE_ADDR)); + + check_stub_type (type); + cp_print_value_fields (type, VALUE_CONTENTS (val), + stream, format, recurse, pretty, + NULL, 1); + return; } + val_print (type, VALUE_CONTENTS (val), VALUE_ADDRESS (val), + stream, format, 0, recurse, pretty); } void @@ -540,5 +617,8 @@ _initialize_cp_valprint () /* Give people the defaults which they are used to. */ objectprint = 0; vtblprint = 0; - obstack_begin (&dont_print_obstack, 32 * sizeof (struct type *)); + obstack_begin (&dont_print_vb_obstack, 32 * sizeof (struct type *)); + obstack_specify_allocation (&dont_print_statmem_obstack, + 32 * sizeof (CORE_ADDR), sizeof (CORE_ADDR), + xmalloc, free); } diff --git a/gdb/elfread.c b/gdb/elfread.c index 326f93c3576..a4d4f72eeda 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -219,7 +219,7 @@ LOCAL FUNCTION SYNOPSIS void elf_symtab_read (bfd *abfd, CORE_ADDR addr, - struct objfile *objfile) + struct objfile *objfile, int dynamic) DESCRIPTION @@ -260,7 +260,7 @@ elf_symtab_read (abfd, addr, objfile, dynamic) asymbol *filesym = 0; #ifdef SOFUN_ADDRESS_MAYBE_MISSING /* Name of filesym, as saved on the symbol_obstack. */ - char *filesymname; + char *filesymname = obsavestring ("", 0, &objfile->symbol_obstack); #endif struct dbx_symfile_info *dbx = (struct dbx_symfile_info *) objfile->sym_stab_info; @@ -304,9 +304,12 @@ elf_symtab_read (abfd, addr, objfile, dynamic) continue; } - if (sym -> section == &bfd_und_section + if (dynamic + && sym -> section == &bfd_und_section && (sym -> flags & BSF_FUNCTION)) { + struct minimal_symbol *msym; + /* Symbol is a reference to a function defined in a shared library. If its value is non zero then it is usually the address @@ -314,17 +317,17 @@ elf_symtab_read (abfd, addr, objfile, dynamic) relative to the base address. If its value is zero then the dynamic linker has to resolve the symbol. We are unable to find any meaningful address - for this symbol in the executable file, so we skip it. - Irix 5 has a zero value for all shared library functions - in the main symbol table, but the dynamic symbol table - provides the right values. */ + for this symbol in the executable file, so we skip it. */ symaddr = sym -> value; if (symaddr == 0) continue; symaddr += addr; - record_minimal_symbol_and_info ((char *) sym -> name, symaddr, - mst_solib_trampoline, NULL, - objfile); + msym = record_minimal_symbol_and_info + ((char *) sym -> name, symaddr, + mst_solib_trampoline, NULL, objfile); +#ifdef SOFUN_ADDRESS_MAYBE_MISSING + msym->filename = filesymname; +#endif continue; } diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 5d4c1eb93ee..32d46c09220 100644 --- a/gdb/f-valprint.c +++ b/gdb/f-valprint.c @@ -1,5 +1,5 @@ /* Support for printing Fortran values for GDB, the GNU debugger. - Copyright 1993, 1994 Free Software Foundation, Inc. + Copyright 1993, 1994, 1995 Free Software Foundation, Inc. Contributed by Motorola. Adapted from the C definitions by Farooq Butt (fmbutt@engage.sps.mot.com), additionally worked over by Stan Shebs. @@ -33,8 +33,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "gdbcore.h" #include "command.h" -extern struct obstack dont_print_obstack; - extern unsigned int print_max; /* No of array elements to print */ extern int calc_f77_array_dims PARAMS ((struct type *)); diff --git a/gdb/findvar.c b/gdb/findvar.c index edf85ee568b..591dc7f987f 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -1,5 +1,5 @@ /* Find a variable's value in memory, for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991 Free Software Foundation, Inc. + Copyright 1986, 1987, 1989, 1991, 1994, 1995 Free Software Foundation, Inc. This file is part of GDB. @@ -25,6 +25,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "gdbcore.h" #include "inferior.h" #include "target.h" +#include static void write_register_pid PARAMS ((int regno, LONGEST val, int pid)); @@ -629,7 +630,6 @@ read_register_pid (regno, pid) #endif /* Store VALUE, into the raw contents of register number REGNO. */ -/* FIXME: The val arg should probably be a LONGEST. */ void write_register (regno, val) diff --git a/gdb/procfs.c b/gdb/procfs.c index 2e8e11f80bc..00e92602b88 100644 --- a/gdb/procfs.c +++ b/gdb/procfs.c @@ -2520,7 +2520,7 @@ set_proc_siginfo (pip, signo) #ifdef PROCFS_DONT_PIOCSSIG_CURSIG /* With Alpha OSF/1 procfs, the kernel gets really confused if it - receives a PIOCSSSIG with a signal identical to the current signal, + receives a PIOCSSIG with a signal identical to the current signal, it messes up the current signal. Work around the kernel bug. */ if (signo == pip -> prstatus.pr_cursig) return; -- 2.30.2