]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdbserver: allow agent expressions to fail with invalid memory access
authorAndrew Burgess <aburgess@redhat.com>
Thu, 20 Oct 2022 10:14:33 +0000 (11:14 +0100)
committerAndrew Burgess <aburgess@redhat.com>
Mon, 3 Apr 2023 13:46:32 +0000 (14:46 +0100)
This commit extends gdbserver to take account of a failed memory
access from agent_mem_read, and to return a new eval_result_type
expr_eval_invalid_memory_access.

I have only updated the agent_mem_read calls related directly to
reading memory, I have not updated any of the calls related to
tracepoint data collection.  This is just because I'm not familiar
with that area of gdb/gdbserver, and I don't want to break anything,
so leaving the existing behaviour untouched seems like the safest
approach.

I've then updated gdb.base/bp-cond-failure.exp to test evaluating the
breakpoints on the target, and have also extended the test so that it
checks for different sizes of memory access.

gdb/testsuite/gdb.base/bp-cond-failure.exp
gdbserver/ax.cc
gdbserver/ax.h

index b528ccce4ade82002e235b89477f42b263116617..cb5722037727d4690936a241b6429d95391535b2 100644 (file)
@@ -47,7 +47,7 @@ if { [is_address_zero_readable] } {
 # Where the breakpoint will be placed.
 set bp_line [gdb_get_line_number "Breakpoint here"]
 
-proc run_test { cond_eval } {
+proc run_test { cond_eval access_type } {
     clean_restart ${::binfile}
 
     if { ![runto_main] } {
@@ -59,7 +59,7 @@ proc run_test { cond_eval } {
     }
 
     # Setup the conditional breakpoint and record its number.
-    gdb_breakpoint "${::srcfile}:${::bp_line} if (*(int *) 0) == 0"
+    gdb_breakpoint "${::srcfile}:${::bp_line} if (*(${access_type} *) 0) == 0"
     set bp_num [get_integer_valueof "\$bpnum" "*UNKNOWN*"]
 
     gdb_test "continue" \
@@ -88,17 +88,7 @@ set cond_eval_modes { "auto" }
 
 gdb_test_multiple "show breakpoint condition-evaluation" "" {
     -re -wrap "Breakpoint condition evaluation mode is auto \\(currently target\\)\\." {
-
-       ## NOTE: Instead of testing with "auto" and "host" in this
-       ## case we only test with "host".  This is because a GDB bug
-       ## prevents the "auto" (a.k.a. target) mode from working.
-       ##
-       ## Don't worry, this will be fixed in a later commit, and this
-       ## comment will be removed at that time.
-       ##
-       ## lappend cond_eval_modes "host"
-
-       set cond_eval_modes { "host" }
+       lappend cond_eval_modes "host"
        pass $gdb_test_name
     }
 
@@ -107,6 +97,8 @@ gdb_test_multiple "show breakpoint condition-evaluation" "" {
     }
 }
 
-foreach_with_prefix cond_eval $cond_eval_modes {
-    run_test $cond_eval
+foreach_with_prefix access_type { "char" "short" "int" "long long" } {
+    foreach_with_prefix cond_eval $cond_eval_modes {
+       run_test $cond_eval $access_type
+    }
 }
index 38ebfbbd7506eb32ec3091f420c8cac4c23200a1..fba5b4ad0fcd89c79ac3c01f7a2357a7f1ffffdc 100644 (file)
@@ -1112,22 +1112,26 @@ gdb_eval_agent_expr (struct eval_agent_expr_context *ctx,
          break;
 
        case gdb_agent_op_ref8:
-         agent_mem_read (ctx, cnv.u8.bytes, (CORE_ADDR) top, 1);
+         if (agent_mem_read (ctx, cnv.u8.bytes, (CORE_ADDR) top, 1) != 0)
+           return expr_eval_invalid_memory_access;
          top = cnv.u8.val;
          break;
 
        case gdb_agent_op_ref16:
-         agent_mem_read (ctx, cnv.u16.bytes, (CORE_ADDR) top, 2);
+         if (agent_mem_read (ctx, cnv.u16.bytes, (CORE_ADDR) top, 2) != 0)
+           return expr_eval_invalid_memory_access;
          top = cnv.u16.val;
          break;
 
        case gdb_agent_op_ref32:
-         agent_mem_read (ctx, cnv.u32.bytes, (CORE_ADDR) top, 4);
+         if (agent_mem_read (ctx, cnv.u32.bytes, (CORE_ADDR) top, 4) != 0)
+           return expr_eval_invalid_memory_access;
          top = cnv.u32.val;
          break;
 
        case gdb_agent_op_ref64:
-         agent_mem_read (ctx, cnv.u64.bytes, (CORE_ADDR) top, 8);
+         if (agent_mem_read (ctx, cnv.u64.bytes, (CORE_ADDR) top, 8) != 0)
+           return expr_eval_invalid_memory_access;
          top = cnv.u64.val;
          break;
 
index 8e64a7a593ebbaec859e5251182f10fad69989fd..c98e36a83c6fea16a37b3151a7209d58a27f7c7a 100644 (file)
@@ -41,7 +41,8 @@ enum eval_result_type
     expr_eval_unhandled_opcode,
     expr_eval_unrecognized_opcode,
     expr_eval_divide_by_zero,
-    expr_eval_invalid_goto
+    expr_eval_invalid_goto,
+    expr_eval_invalid_memory_access
   };
 
 struct agent_expr