summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Burgess <aburgess@redhat.com>2023-05-09 12:13:02 +0100
committerAndrew Burgess <aburgess@redhat.com>2023-05-10 14:53:41 +0100
commit16c8122639ca0948f56fce125b3ad46e122d1edc (patch)
tree3d195c2ba019781cb3aac4df99285a9130bfdf82
parent6109320673fe30163b5d00d9e3a7f4e77befb22a (diff)
downloadbinutils-gdb-16c8122639ca0948f56fce125b3ad46e122d1edc.tar.gz
gdb/rust: fix crash for expression debug with strings
While working on another patch I did this: (gdb) set debug expression 1 (gdb) set language rust (gdb) p "foo" Operation: OP_AGGREGATE Type: &str Fatal signal: Segmentation fault ... etc ... The problem is that the second field of the rust_aggregate_operation is created as a nullptr, this can be seen in rust-parse.c. in the function rust_parser::parse_string(). However, in expop.h, in the function dump_for_expression, we make the assumption that the expressions will never be nullptr. I did consider moving the nullptr handling into a new function rust_aggregate_operation::dump, however, as the expression debug dumping code is not exercised as much as it might be, I would rather that this code be hardened and able to handle a nullptr without crashing, so I propose that we add nullptr handling into the general dump_for_expression function. The behaviour is now: (gdb) set debug expression 1 (gdb) set language rust (gdb) p "foo" Operation: OP_AGGREGATE Type: &str nullptr Vector: String: data_ptr Operation: UNOP_ADDR Operation: OP_STRING String: foo String: length Operation: OP_LONG Type: usize Constant: 3 evaluation of this expression requires the target program to be active (gdb) There's a new test to check for this case. Reviewed-By: Tom Tromey <tom@tromey.com>
-rw-r--r--gdb/expop.h5
-rw-r--r--gdb/testsuite/gdb.rust/expr.exp21
2 files changed, 25 insertions, 1 deletions
diff --git a/gdb/expop.h b/gdb/expop.h
index 854945c8688..a9da11cc70d 100644
--- a/gdb/expop.h
+++ b/gdb/expop.h
@@ -314,7 +314,10 @@ static inline void
dump_for_expression (struct ui_file *stream, int depth,
const operation_up &op)
{
- op->dump (stream, depth);
+ if (op == nullptr)
+ gdb_printf (stream, _("%*snullptr\n"), depth, "");
+ else
+ op->dump (stream, depth);
}
extern void dump_for_expression (struct ui_file *stream, int depth,
diff --git a/gdb/testsuite/gdb.rust/expr.exp b/gdb/testsuite/gdb.rust/expr.exp
index 908d1a3680b..ce2cce2677c 100644
--- a/gdb/testsuite/gdb.rust/expr.exp
+++ b/gdb/testsuite/gdb.rust/expr.exp
@@ -148,3 +148,24 @@ gdb_test "print r#" "No symbol 'r' in current context"
gdb_test "printf \"%d %d\\n\", 23+1, 23-1" "24 22"
gdb_test "print 5," "Syntax error near ','"
+
+# Check expression debug works for strings.
+gdb_test "with debug expression 1 -- print \"foo\"" \
+ [multi_line \
+ "Operation: OP_AGGREGATE" \
+ " Type: &str" \
+ " nullptr" \
+ " Vector:" \
+ " String: data_ptr" \
+ " Operation: UNOP_ADDR" \
+ " Operation: OP_STRING" \
+ " String: foo" \
+ " String: length" \
+ " Operation: OP_LONG" \
+ " Type: usize" \
+ " Constant: 3" \
+ "Operation: OP_LONG" \
+ " Type: i32" \
+ " Constant: 0" \
+ "evaluation of this expression requires the target program to be active"] \
+ "print a string with expression debug turned on"