aboutsummaryrefslogtreecommitdiff
path: root/gdb/cp-valprint.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/cp-valprint.c')
-rw-r--r--gdb/cp-valprint.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index b2015c7..a4027ea 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -30,6 +30,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "annotate.h"
#include "gdb_string.h"
#include "c-lang.h"
+#include "target.h"
int vtblprint; /* Controls printing of vtbl's */
int objectprint; /* Controls looking up an object's derived type
@@ -410,6 +411,7 @@ cp_print_value (type, valaddr, address, stream, format, recurse, pretty,
int boffset;
struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
char *basename = TYPE_NAME (baseclass);
+ char *base_valaddr;
if (BASETYPE_VIA_VIRTUAL (type, i))
{
@@ -438,10 +440,25 @@ cp_print_value (type, valaddr, address, stream, format, recurse, pretty,
baseclass name. */
fputs_filtered (basename ? basename : "", stream);
fputs_filtered ("> = ", stream);
+
+ /* The virtual base class pointer might have been clobbered by the
+ user program. Make sure that it still points to a valid memory
+ location. */
+
+ if (boffset != -1 && (boffset < 0 || boffset >= TYPE_LENGTH (type)))
+ {
+ base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass));
+ if (target_read_memory (address + boffset, base_valaddr,
+ TYPE_LENGTH (baseclass)) != 0)
+ boffset = -1;
+ }
+ else
+ base_valaddr = valaddr + boffset;
+
if (boffset == -1)
fprintf_filtered (stream, "<invalid address>");
else
- cp_print_value_fields (baseclass, valaddr + boffset, address + boffset,
+ cp_print_value_fields (baseclass, base_valaddr, address + boffset,
stream, format, recurse, pretty,
(struct type **) obstack_base (&dont_print_vb_obstack),
0);