From bd0b9f9e12441312c46482764448a8a8ce236107 Mon Sep 17 00:00:00 2001 From: Joel Brobecker Date: Wed, 21 Mar 2012 15:16:24 +0000 Subject: [PATCH] SEGV during AX eval of OP_DOUBLE (unsupported) To reproduce the problem, simply try the following with any program: (gdb) maintenance agent-eval 1.0 Critical error handler: process [...] terminated due to access violation (this is on Windows; on GNU/Linux, the libc copes better) The problem is quite simple: gen_expr is given an expression that contains an unrecognized operator (OP_DOUBLE in this case). When that happens, it tries to report an error with a string image of the operator in the error message. Conversion of the opcode into a string is done using op_string which, despite its name, probably is not what the author was looking for. This function returns NULL for a lot of the opcodes, thus triggering the crash. There is a function that corresponds to what we are looking for: expprint.c:op_name. It was static, though, so I made it non-static, and used it from ax-gdb.c:gen_expr. gdb/ChangeLog: * expression.h (op_name): Add declaration. * expprint.c (op_name): Remove declaration. Make non-static. * ax-gdb.c (gen_expr): Use op_name instead of op_string. --- gdb/ChangeLog | 6 ++++++ gdb/ax-gdb.c | 2 +- gdb/expprint.c | 3 +-- gdb/expression.h | 2 ++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 53440677db..aff420c29e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2012-03-21 Joel Brobecker + + * expression.h (op_name): Add declaration. + * expprint.c (op_name): Remove declaration. Make non-static. + * ax-gdb.c (gen_expr): Use op_name instead of op_string. + 2012-03-21 Thomas Schwinge * amd64-linux-nat.c (amd64_linux_siginfo_fixup): Use siginfo_t instead diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index a76e781720..aaefed6f6a 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -2217,7 +2217,7 @@ gen_expr (struct expression *exp, union exp_element **pc, default: error (_("Unsupported operator %s (%d) in expression."), - op_string (op), op); + op_name (exp, op), op); } } diff --git a/gdb/expprint.c b/gdb/expprint.c index d9d9b8fc87..fd1fccb069 100644 --- a/gdb/expprint.c +++ b/gdb/expprint.c @@ -647,12 +647,11 @@ op_string (enum exp_opcode op) /* Support for dumping the raw data from expressions in a human readable form. */ -static char *op_name (struct expression *, enum exp_opcode); static int dump_subexp_body (struct expression *exp, struct ui_file *, int); /* Name for OPCODE, when it appears in expression EXP. */ -static char * +char * op_name (struct expression *exp, enum exp_opcode opcode) { return exp->language_defn->la_exp_desc->op_name (opcode); diff --git a/gdb/expression.h b/gdb/expression.h index be26002998..ace58f2b47 100644 --- a/gdb/expression.h +++ b/gdb/expression.h @@ -137,6 +137,8 @@ extern struct value *evaluate_subexp_standard extern void print_expression (struct expression *, struct ui_file *); +extern char *op_name (struct expression *exp, enum exp_opcode opcode); + extern char *op_string (enum exp_opcode); extern void dump_raw_expression (struct expression *, -- 2.34.1