From: Andrew Burgess Date: Tue, 9 May 2023 11:13:02 +0000 (+0100) Subject: gdb/rust: fix crash for expression debug with strings X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=16c8122639ca0948f56fce125b3ad46e122d1edc;p=binutils-gdb.git 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 --- 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"