OSDN Git Service

* library/session.tcl (session_save): Save breakpoints.
authorTom Tromey <tromey@redhat.com>
Mon, 11 Jun 2001 23:08:05 +0000 (23:08 +0000)
committerTom Tromey <tromey@redhat.com>
Mon, 11 Jun 2001 23:08:05 +0000 (23:08 +0000)
(SESSION_serialize_bps): New proc.
(SESSION_recreate_bps): New proc.
(session_load): Recreate breakpoints.
* library/util.tcl (bp_exists): Expect user specification in
breakpoint info.
* library/srctextwin.itb (SrcTextWin::showBPBalloon): Expect user
specification in breakpoint info.
* library/gdbevent.itb (BreakpointEvent::_init): Initialize
_user_specification.
(BreakpointEvent::get): Handle user_specification.
* library/gdbevent.ith (BreakpointEvent): Added
_user_specification field.
* library/bpwin.itb (BpWin::bp_store): Expect user specification
and use it when saving.
(BpWin::bp_type): Expect user specification.
* generic/gdbtk-bp.c (BREAKPOINT_IS_WATCHPOINT): New macro.
(gdb_get_breakpoint_info): Added `user specification' to result.

gdb/gdbtk/ChangeLog
gdb/gdbtk/generic/gdbtk-bp.c
gdb/gdbtk/library/bpwin.itb
gdb/gdbtk/library/gdbevent.itb
gdb/gdbtk/library/gdbevent.ith
gdb/gdbtk/library/session.tcl
gdb/gdbtk/library/srctextwin.itb
gdb/gdbtk/library/util.tcl

index a945e5e..25ff09e 100644 (file)
@@ -1,3 +1,24 @@
+2001-06-11  Tom Tromey  <tromey@redhat.com>
+
+       * library/session.tcl (session_save): Save breakpoints.
+       (SESSION_serialize_bps): New proc.
+       (SESSION_recreate_bps): New proc.
+       (session_load): Recreate breakpoints.
+       * library/util.tcl (bp_exists): Expect user specification in
+       breakpoint info.
+       * library/srctextwin.itb (SrcTextWin::showBPBalloon): Expect user
+       specification in breakpoint info.
+       * library/gdbevent.itb (BreakpointEvent::_init): Initialize
+       _user_specification.
+       (BreakpointEvent::get): Handle user_specification.
+       * library/gdbevent.ith (BreakpointEvent): Added
+       _user_specification field.
+       * library/bpwin.itb (BpWin::bp_store): Expect user specification
+       and use it when saving.
+       (BpWin::bp_type): Expect user specification.
+       * generic/gdbtk-bp.c (BREAKPOINT_IS_WATCHPOINT): New macro.
+       (gdb_get_breakpoint_info): Added `user specification' to result.
+
 2001-06-11  Keith Seitz  <keiths@redhat.com>
 
        * generic/gdbtk-stack.c (gdb_stack): Return TCL_ERROR if
index 4f65e35..ab6aa1e 100644 (file)
@@ -62,6 +62,13 @@ char *bpdisp[] =
  || (bp)->type == bp_read_watchpoint     \
  || (bp)->type == bp_access_watchpoint)
 
+/* Is this breakpoint a watchpoint?  */
+#define BREAKPOINT_IS_WATCHPOINT(bp)                                         \
+((bp)->type == bp_watchpoint                                                 \
+ || (bp)->type == bp_hardware_watchpoint                                     \
+ || (bp)->type == bp_read_watchpoint                                         \
+ || (bp)->type == bp_access_watchpoint)
+
 /*
  * These are routines we need from breakpoint.c.
  * at some point make these static in breakpoint.c and move GUI code there
@@ -279,7 +286,7 @@ gdb_find_bp_at_line (clientData, interp, objc, objv)
  * Tcl Result:
  *   A list with {file, function, line_number, address, type, enabled?,
  *                disposition, ignore_count, {list_of_commands},
- *                condition, thread, hit_count}
+ *                condition, thread, hit_count user_specification}
  */
 static int
 gdb_get_breakpoint_info (ClientData clientData, Tcl_Interp *interp, int objc,
@@ -356,6 +363,11 @@ gdb_get_breakpoint_info (ClientData clientData, Tcl_Interp *interp, int objc,
   Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
                            Tcl_NewIntObj (b->hit_count));
 
+  Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr,
+                           Tcl_NewStringObj (BREAKPOINT_IS_WATCHPOINT (b)
+                                             ? b->exp_string
+                                             : b->addr_string, -1));
+
   return TCL_OK;
 }
 
index 0ea50d1..d3c6705 100644 (file)
@@ -298,18 +298,21 @@ body BpWin::bp_store {} {
   foreach breakpoint [gdb_get_breakpoint_list] {
     # This is an lassign
     foreach {file function line_no address type \
-              enable_p disp ignore cmds thread hit_count} \
+              enable_p disp ignore cmds thread hit_count user_spec} \
       [gdb_get_breakpoint_info $breakpoint] {
        break
       }
 
-    if {$file != ""} {
+    if {$user_spec != ""} {
+      set bp_specifier $user_spec
+    } elseif {$file != ""} {
       set filename [file tail $file]
       set bp_specifier $filename:$line_no
     } else {
       set bp_specifier *$address
     }
 
+    # FIXME: doesn't handle watchpoints.
     if {[string compare $disp "delete"] == 0} {
       puts $outH "tbreak $bp_specifier"
     } else {
@@ -542,7 +545,7 @@ body BpWin::bp_type { i } {
   #debug "bp_type $i $bpnum"
   set bpinfo [gdb_get_breakpoint_info $bpnum]
   lassign $bpinfo file func line pc type enabled disposition \
-    ignore_count commands cond thread hit_count
+    ignore_count commands cond thread hit_count user_spec
   bp_select $i
   switch $disposition {
     delete {  
index eab64f0..b781a8e 100644 (file)
@@ -31,8 +31,9 @@ body BreakpointEvent::get {what} {
     condition    { return $_condition }
     thread       { return $_thread }
     hit_count    { return $_hit_count }
+    user_specification { return $_user_specification }
 
-    default { error "unknown event data \"$what\": should be: action|number|file|function|line|address|type|enabled|disposition|ignore_count|commands|condition|thread|hit_count" }
+    default { error "unknown event data \"$what\": should be: action|number|file|function|line|address|type|enabled|disposition|ignore_count|commands|condition|thread|hit_count|user_specification" }
   }
 }
 
@@ -53,6 +54,7 @@ body BreakpointEvent::_init {} {
     set _condition    {}
     set _thread       {}
     set _hit_count    {}
+    set _user_specification {}
   } else {
     lassign $bpinfo \
       _file         \
@@ -66,7 +68,8 @@ body BreakpointEvent::_init {} {
       _commands     \
       _condition    \
       _thread       \
-      _hit_count
+      _hit_count    \
+      _user_specification
   }
 }
 
index dd45f97..25074e6 100644 (file)
@@ -40,6 +40,8 @@ class GDBEvent {
 # condition .... BP condition
 # thread ....... thread in which BP is set (or -1 for all threads) 
 # hit_count .... number of times BP has been hit
+# user_specification
+#             .. text the user initially used to set this breakpoint
 class BreakpointEvent {
   inherit GDBEvent
 
@@ -71,6 +73,7 @@ class BreakpointEvent {
   private variable _condition    {}
   private variable _thread       {}
   private variable _hit_count    {}
+  private variable _user_specification {}
 
   private method _init {}
 }
index 50f2c3d..4c47770 100644 (file)
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 
+# An internal function used when saving sessions.  Returns a string
+# that can be used to recreate all pertinent breakpoint state.
+proc SESSION_serialize_bps {} {
+  set result {}
+
+  foreach bp_num [gdb_get_breakpoint_list] {
+    lassign [gdb_get_breakpoint_info $bp_num] file function line_number \
+      address type enabled disposition ignore_count command_list \
+      condition thread hit_count user_specification
+
+    switch -glob -- $type {
+      "breakpoint" -
+      "hw breakpoint" {
+       if {$disposition == "delete"} {
+         set cmd tbreak
+       } else {
+         set cmd break
+       }
+
+       append cmd " "
+       if {$user_specification != ""} {
+         append cmd "$user_specification"
+       } elseif {$file != ""} {
+         # BpWin::bp_store uses file tail here, but I think that is
+         # wrong.
+         append cmd "$file:$line_number"
+       } else {
+         append cmd "*$address"
+       }
+      }
+      "watchpoint" -
+      "hw watchpoint" {
+       set cmd watch
+       if {$user_specification != ""} {
+         append cmd " $user_specification"
+       } else {
+         # There's nothing sensible to do.
+         continue
+       }
+      }
+
+      "catch*" {
+       # FIXME: Don't know what to do.
+       continue
+      }
+
+      default {
+       # Can't serialize anything other than those listed above.
+       continue
+      }
+    }
+
+    lappend result [list $cmd $enabled $condition $command_list]
+  }
+
+  return $result
+}
+
+# An internal function used when loading sessions.  It takes a
+# breakpoint string and recreates all the breakpoints.
+proc SESSION_recreate_bps {specs} {
+  foreach spec $specs {
+    lassign $spec create enabled condition commands
+
+    # Create the breakpoint
+    gdb_cmd $create
+
+    # Below we use `\$bpnum'.  This means we don't have to figure out
+    # the number of the breakpoint when doing further manipulations.
+
+    if {! $enabled} {
+      gdb_cmd "disable \$bpnum"
+    }
+
+    if {$condition != ""} {
+      gdb_cmd "cond \$bpnum $condition"
+    }
+
+    if {[llength $commands]} {
+      lappend commands end
+      gdb_cmd "commands \$bpnum\n[join $commands \n]"
+    }
+  }
+}
+
 #
 # This procedure decides what makes up a gdb `session'.  Roughly a
 # session is whatever the user found useful when debugging a certain
@@ -39,6 +124,9 @@ proc session_save {} {
   set values(pwd) $gdb_current_directory
   set values(target) $gdb_target_name
 
+  # Breakpoints.
+  set values(breakpoints) [SESSION_serialize_bps]
+
   # Recompute list of recent sessions.  Trim to no more than 5 sessions.
   set recent [concat [list $name] \
                [lremove [pref getd gdb/recent-projects] $name]]
@@ -88,6 +176,10 @@ proc session_load {name} {
     set_exe
   }
 
+  if {[info exists values(breakpoints)]} {
+    SESSION_recreate_bps $values(breakpoints)
+  }
+
   if {[info exists values(target)]} {
     debug "Restoring Target: $values(target)"
     set gdb_target_name $values(target)
index 857dc86..7850032 100644 (file)
@@ -2314,7 +2314,7 @@ body SrcTextWin::showBPBalloon {win x y} {
   foreach b $bps {
     set bpinfo [gdb_get_breakpoint_info $b]
     lassign $bpinfo file func linenum addr type enabled disposition \
-      ignore_count commands cond thread hit_count
+      ignore_count commands cond thread hit_count user_specification
     if {$thread == "-1"} {set thread "all"}
     set file [lindex [file split $file] end]
     if {$enabled} {
index 495e71e..fb227ad 100644 (file)
@@ -175,7 +175,7 @@ proc bp_exists {linespec} {
   foreach bpnum $bps {
     set bpinfo [gdb_get_breakpoint_info $bpnum]
     lassign $bpinfo file func line pc type enabled disposition \
-      ignore_count commands cond thread hit_count
+      ignore_count commands cond thread hit_count user_specification
     if {$filename == $file && $function == $func && $addr == $pc} {
       return $bpnum
     }