breakpoints: add rwp all command 07/7907/8
authorMarek Vrbka <marek.vrbka@codasip.com>
Fri, 22 Sep 2023 11:57:04 +0000 (13:57 +0200)
committerAntonio Borneo <borneo.antonio@gmail.com>
Sat, 14 Oct 2023 12:01:38 +0000 (12:01 +0000)
This patch adds the "all" option to the rwp command.
It removes all watchpoints, much like rbp all removes
all breakpoints.

Change-Id: Id58dd103085e558f17afa4a287888cf085566ca9
Signed-off-by: Marek Vrbka <marek.vrbka@codasip.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/7907
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
doc/openocd.texi
src/target/breakpoints.c
src/target/breakpoints.h
src/target/target.c

index 6ec280ad237a8095984c7b50c2b3092fbb257fed..a2965189fbb3aca12eaf5e9bf469eadfd92e0444 100644 (file)
@@ -9358,8 +9358,8 @@ for similar mechanisms that do not consume hardware breakpoints.)
 Remove the breakpoint at @var{address} or all breakpoints.
 @end deffn
 
-@deffn {Command} {rwp} address
-Remove data watchpoint on @var{address}
+@deffn {Command} {rwp} @option{all} | address
+Remove data watchpoint on @var{address} or all watchpoints.
 @end deffn
 
 @deffn {Command} {wp} [address len [(@option{r}|@option{w}|@option{a}) [value [mask]]]]
index 4a613cc284f8d9c64113e3987c44ed8a3b31dad4..07d0a7371056b9ad21ea57711312b3f14bec5dac 100644 (file)
 #include "breakpoints.h"
 #include "smp.h"
 
+enum breakpoint_watchpoint {
+       BREAKPOINT,
+       WATCHPOINT,
+};
+
 static const char * const breakpoint_type_strings[] = {
        "hardware",
        "software"
@@ -375,26 +380,90 @@ int breakpoint_remove(struct target *target, target_addr_t address)
        return retval;
 }
 
-int breakpoint_remove_all(struct target *target)
+static int watchpoint_free(struct target *target, struct watchpoint *watchpoint_to_remove)
+{
+       struct watchpoint *watchpoint = target->watchpoints;
+       struct watchpoint **watchpoint_p = &target->watchpoints;
+       int retval;
+
+       while (watchpoint) {
+               if (watchpoint == watchpoint_to_remove)
+                       break;
+               watchpoint_p = &watchpoint->next;
+               watchpoint = watchpoint->next;
+       }
+
+       if (!watchpoint)
+               return ERROR_OK;
+       retval = target_remove_watchpoint(target, watchpoint);
+       if (retval != ERROR_OK) {
+               LOG_TARGET_ERROR(target, "could not remove watchpoint #%d on this target",
+                                                watchpoint->number);
+               return retval;
+       }
+
+       LOG_DEBUG("free WPID: %d --> %d", watchpoint->unique_id, retval);
+       (*watchpoint_p) = watchpoint->next;
+       free(watchpoint);
+
+       return ERROR_OK;
+}
+
+static int watchpoint_remove_all_internal(struct target *target)
+{
+       struct watchpoint *watchpoint = target->watchpoints;
+       int retval = ERROR_OK;
+
+       while (watchpoint) {
+               struct watchpoint *tmp = watchpoint;
+               watchpoint = watchpoint->next;
+               int status = watchpoint_free(target, tmp);
+               if (status != ERROR_OK)
+                       retval = status;
+       }
+
+       return retval;
+}
+
+int breakpoint_watchpoint_remove_all(struct target *target, enum breakpoint_watchpoint bp_wp)
 {
+       assert(bp_wp == BREAKPOINT || bp_wp == WATCHPOINT);
        int retval = ERROR_OK;
        if (target->smp) {
                struct target_list *head;
 
                foreach_smp_target(head, target->smp_targets) {
                        struct target *curr = head->target;
-                       int status = breakpoint_remove_all_internal(curr);
+
+                       int status = ERROR_OK;
+                       if (bp_wp == BREAKPOINT)
+                               status = breakpoint_remove_all_internal(curr);
+                       else
+                               status = watchpoint_remove_all_internal(curr);
 
                        if (status != ERROR_OK)
                                retval = status;
                }
        } else {
-               retval = breakpoint_remove_all_internal(target);
+               if (bp_wp == BREAKPOINT)
+                       retval = breakpoint_remove_all_internal(target);
+               else
+                       retval = watchpoint_remove_all_internal(target);
        }
 
        return retval;
 }
 
+int breakpoint_remove_all(struct target *target)
+{
+       return breakpoint_watchpoint_remove_all(target, BREAKPOINT);
+}
+
+int watchpoint_remove_all(struct target *target)
+{
+       return breakpoint_watchpoint_remove_all(target, WATCHPOINT);
+}
+
 static int breakpoint_clear_target_internal(struct target *target)
 {
        LOG_DEBUG("Delete all breakpoints for target: %s",
@@ -532,35 +601,6 @@ int watchpoint_add(struct target *target, target_addr_t address,
        }
 }
 
-static int watchpoint_free(struct target *target, struct watchpoint *watchpoint_to_remove)
-{
-       struct watchpoint *watchpoint = target->watchpoints;
-       struct watchpoint **watchpoint_p = &target->watchpoints;
-       int retval;
-
-       while (watchpoint) {
-               if (watchpoint == watchpoint_to_remove)
-                       break;
-               watchpoint_p = &watchpoint->next;
-               watchpoint = watchpoint->next;
-       }
-
-       if (!watchpoint)
-               return ERROR_OK;
-       retval = target_remove_watchpoint(target, watchpoint);
-       if (retval != ERROR_OK) {
-               LOG_TARGET_ERROR(target, "could not remove watchpoint #%d on this target",
-                                               watchpoint->number);
-               return retval;
-       }
-
-       LOG_DEBUG("free WPID: %d --> %d", watchpoint->unique_id, retval);
-       (*watchpoint_p) = watchpoint->next;
-       free(watchpoint);
-
-       return ERROR_OK;
-}
-
 static int watchpoint_remove_internal(struct target *target, target_addr_t address)
 {
        struct watchpoint *watchpoint = target->watchpoints;
index daa31f711c8f4aab592528b29590932f6f507065..64c0ce2a5ae1653b589e123eeb5fe55b2fff0243 100644 (file)
@@ -73,6 +73,7 @@ int watchpoint_add(struct target *target,
                target_addr_t address, uint32_t length,
                enum watchpoint_rw rw, uint64_t value, uint64_t mask);
 int watchpoint_remove(struct target *target, target_addr_t address);
+int watchpoint_remove_all(struct target *target);
 
 /* report type and address of just hit watchpoint */
 int watchpoint_hit(struct target *target, enum watchpoint_rw *rw,
index acd351a66c35d41ff052e2eefc21a73f3ab65018..bed8a2cbc4250e302f92d2ffa160109bef2e3fe8 100644 (file)
@@ -4136,17 +4136,28 @@ COMMAND_HANDLER(handle_wp_command)
 
 COMMAND_HANDLER(handle_rwp_command)
 {
+       int retval;
+
        if (CMD_ARGC != 1)
                return ERROR_COMMAND_SYNTAX_ERROR;
 
-       target_addr_t addr;
-       COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);
-
        struct target *target = get_current_target(CMD_CTX);
-       int retval = watchpoint_remove(target, addr);
+       if (!strcmp(CMD_ARGV[0], "all")) {
+               retval = watchpoint_remove_all(target);
 
-       if (retval != ERROR_OK)
-               command_print(CMD, "Error during removal of watchpoint at address " TARGET_ADDR_FMT, addr);
+               if (retval != ERROR_OK) {
+                       command_print(CMD, "Error encountered during removal of all watchpoints.");
+                       command_print(CMD, "Some watchpoints may have remained set.");
+               }
+       } else {
+               target_addr_t addr;
+               COMMAND_PARSE_ADDRESS(CMD_ARGV[0], addr);
+
+               retval = watchpoint_remove(target, addr);
+
+               if (retval != ERROR_OK)
+                       command_print(CMD, "Error during removal of watchpoint at address " TARGET_ADDR_FMT, addr);
+       }
 
        return retval;
 }
@@ -7065,7 +7076,7 @@ static const struct command_registration target_exec_command_handlers[] = {
                .handler = handle_rwp_command,
                .mode = COMMAND_EXEC,
                .help = "remove watchpoint",
-               .usage = "address",
+               .usage = "'all' | address",
        },
        {
                .name = "load_image",

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)