aboutsummaryrefslogtreecommitdiff
path: root/libctf/ctf-dump.c
diff options
context:
space:
mode:
authorStephan Rohr <stephan.rohr@intel.com>2025-08-20 06:06:23 -0700
committerStephan Rohr <stephan.rohr@intel.com>2025-09-24 01:31:52 -0700
commit3a3c3a0e7280ef8907d62ea83706a2ef3081831b (patch)
tree70c20a5448526e6d61dbd4c30a4349a0782b2c41 /libctf/ctf-dump.c
parent4c47471ba4cfd59206ce1cb33ae2f19ced2f29cd (diff)
downloadbinutils-3a3c3a0e7280ef8907d62ea83706a2ef3081831b.zip
binutils-3a3c3a0e7280ef8907d62ea83706a2ef3081831b.tar.gz
binutils-3a3c3a0e7280ef8907d62ea83706a2ef3081831b.tar.bz2
gdb: resolve type to target_type in expression evaluation
If an expression is evaluated with 'EVAL_AVOID_SIDE_EFFECTS', we're essentially interested in compatibility of the operands. If there is an operand of reference type, this would give us a memory value that would cause a failure if GDB attempts to access the contents. GDB fails to evaluate binary expressions for the following example: struct { int &get () { return x; }; int x = 1; } v_struct; The GDB output is: (gdb) print v_struct3.get () == 1 && v_struct3.get () == 2 Cannot access memory at address 0x0 (gdb) print v_struct3.get () == 1 || v_struct3.get () == 2 Cannot access memory at address 0x0 Likewise, GDB fails to resolve the type for some expressions: (gdb) ptype v_struct.get () type = int & (gdb) ptype v_struct.get () == 1 Cannot access memory at address 0x0 (gdb) ptype v_struct.get () + 1 Cannot access memory at address 0x0 (gdb) ptype v_struct.get () && 1 Cannot access memory at address 0x0 (gdb) ptype v_struct.get () || 1 Cannot access memory at address 0x0 (gdb) ptype !v_struct.get () Cannot access memory at address 0x0 (gdb) ptype v_struct.get () ? 2 : 3 Cannot access memory at address 0x0 (gdb) ptype v_struct.get () | 1 Cannot access memory at address 0x0 Expression evaluation uses helper functions such as 'value_equal', 'value_logical_not', etc. These helper functions do not take a 'noside' argument and if one of their value arguments was created from a function call that returns a reference type when noside == EVAL_AVOID_SIDE_EFFECTS, GDB attempts to read from an invalid memory location. Consider the following call stack of the 'ptype v_struct.get () + 1' command at the time of assertion when the memory error is raised: #0 memory_error (err=TARGET_XFER_E_IO, memaddr=0) at gdb/corefile.c:114 #1 read_value_memory (val=.., bit_offset=0, stack=false, memaddr=0, buffer=.. "", length=4) at gdb/valops.c:1075 #2 value::fetch_lazy_memory (this=..) at gdb/value.c:3996 #3 value::fetch_lazy (this=..) at gdb/value.c:4135 #4 value::contents_writeable (this=..) at gdb/value.c:1329 #5 value::contents (this=..) at gdb/value.c:1319 #6 value_as_mpz (val=..) at gdb/value.c:2685 #7 scalar_binop (arg1=.., arg2=.., op=BINOP_ADD) at gdb/valarith.c:1240 #8 value_binop (arg1=.., arg2=.., op=BINOP_ADD) at gdb/valarith.c:1489 #9 eval_op_add (expect_type=0x0, exp=.., noside=EVAL_AVOID_SIDE_EFFECTS, arg1=.., arg2=..) at gdb/eval.c:1333 #10 expr::add_operation::evaluate (this=.., expect_type=0x0, exp=.., noside=EVAL_AVOID_SIDE_EFFECTS) at gdb/expop.h:1209 #11 expression::evaluate (this=.., expect_type=0x0, noside=EVAL_AVOID_SIDE_EFFECTS) at gdb/eval.c:110 #12 expression::evaluate_type (this=..) at gdb/expression.h:242 'add_operation::evaluate' calls the helper 'eval_op_add' which attempts to read from the unresolved memory location. Convert to the target type to avoid such problems. The patch is implemented in 'expop.h' for the following reasons: * Support templated classes without explicit helpers, e.g., 'binop_operation' and 'comparison_operation'. * Stripping references in 'binop_promote' requires additional refactoring beyond this patch as we would need to carry on the 'noside' parameter. The above failures are resolved with the patch: (gdb) print v_struct.get () == 1 && v_struct3.get () == 2 $1 = false (gdb) print v_struct.get () == 1 || v_struct3.get () == 2 $2 = true (gdb) ptype v_struct.get () type = int & (gdb) ptype v_struct.get () == 1 type = bool (gdb) ptype v_struct.get () + 1 type = int (gdb) ptype v_struct.get () && 1 type = bool (gdb) ptype v_struct.get () || 1 type = bool (gdb) ptype !v_struct.get () type = bool (gdb) ptype v_struct.get () ? 2 : 3 type = int (gdb) ptype v_struct.get () | 1 type = int Co-Authored-By: Tankut Baris Aktemur <tankut.baris.aktemur@intel.com> Approved-By: Tom Tromey <tom@tromey.com>
Diffstat (limited to 'libctf/ctf-dump.c')
0 files changed, 0 insertions, 0 deletions