]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2008-10-02 Michael Snyder <msnyder@vmware.com>
authorMichael Snyder <msnyder@vmware.com>
Fri, 3 Oct 2008 17:50:15 +0000 (17:50 +0000)
committerMichael Snyder <msnyder@vmware.com>
Fri, 3 Oct 2008 17:50:15 +0000 (17:50 +0000)
* record.c (record_open): Call target_can_async_p() instead
of relying on a global variable.
* record.h (record_linux_async_permitted): Delete.
* linux-nat.h (record_linux_async_permitted): Delete reference.

gdb/linux-nat.c
gdb/record.c
gdb/record.h

index a0dc634ff8300da395b04553cd51b3cb3109c551..7d94a68404de533596e1f1f044cd460d700a53fb 100644 (file)
@@ -50,6 +50,8 @@
 #include "event-loop.h"
 #include "event-top.h"
 
+#include "record.h"
+
 #ifdef HAVE_PERSONALITY
 # include <sys/personality.h>
 # if !HAVE_DECL_ADDR_NO_RANDOMIZE
@@ -503,6 +505,107 @@ my_waitpid (int pid, int *status, int flags)
   return ret;
 }
 
+extern struct bp_location *bp_location_chain;
+static struct lwp_info * find_lwp_pid (ptid_t ptid);
+static int
+my_waitpid_record (int pid, int *status, int flags)
+{
+  int ret;
+  struct bp_location *bl;
+  struct breakpoint *b;
+  CORE_ADDR pc;
+  struct lwp_info *lp;
+
+wait_begin:
+  ret = my_waitpid (pid, status, flags);
+  if (ret == -1)
+    {
+      return ret;
+    }
+
+  if (ret == 0)
+    {
+      goto wait_begin;
+    }
+
+  if (WIFSTOPPED (*status) && WSTOPSIG (*status) == SIGTRAP)
+    {
+      /* Check if there is a breakpoint */
+      pc = 0;
+      registers_changed ();
+      for (bl = bp_location_chain; bl; bl = bl->global_next)
+       {
+         b = bl->owner;
+         gdb_assert (b);
+         if (b->enable_state != bp_enabled
+             && b->enable_state != bp_permanent)
+           continue;
+         if (!pc)
+           {
+             pc = regcache_read_pc (get_thread_regcache (pid_to_ptid (ret)));
+           }
+         switch (b->type)
+           {
+           default:
+             if (bl->address == pc)
+               {
+                 goto out;
+               }
+             break;
+
+           case bp_watchpoint:
+             /*XXX teawater: I still not very clear how to deal with it. */
+             goto out;
+             break;
+
+           case bp_catch_fork:
+             if (inferior_has_forked (inferior_ptid, &b->forked_inferior_pid))
+               {
+                 goto out;
+               }
+             break;
+
+           case bp_catch_vfork:
+             if (inferior_has_vforked (inferior_ptid, &b->forked_inferior_pid))
+               {
+                 goto out;
+               }
+             break;
+
+           case bp_catch_exec:
+             if (inferior_has_execd (inferior_ptid, &b->exec_pathname))
+               {
+                 goto out;
+               }
+             break;
+
+           case bp_hardware_watchpoint:
+           case bp_read_watchpoint:
+           case bp_access_watchpoint:
+             if (STOPPED_BY_WATCHPOINT (0))
+               {
+                 goto out;
+               }
+             break;
+           }
+       }
+
+      lp = find_lwp_pid (pid_to_ptid (ret));
+      if (lp)
+        lp->stopped = 1;
+
+      /* record message */
+      record_message (current_gdbarch);
+
+      /* resume program */
+      linux_ops->to_resume (pid_to_ptid (ret), 1, TARGET_SIGNAL_0);
+      goto wait_begin;
+    }
+
+out:
+  return ret;
+}
+
 /* Determine if PTRACE_O_TRACEFORK can be used to follow fork events.
 
    First, we try to enable fork tracing on ORIGINAL_PID.  If this fails,
@@ -2860,7 +2963,16 @@ retry:
           queued events.  */
        lwpid = queued_waitpid (pid, &status, options);
       else
-       lwpid = my_waitpid (pid, &status, options);
+       {
+         if (RECORD_IS_USED && !record_resume_step)
+           {
+             lwpid = my_waitpid_record (pid, &status, options);
+           }
+         else
+           {
+             lwpid = my_waitpid (pid, &status, options);
+           }
+       }
 
       if (lwpid > 0)
        {
@@ -4441,6 +4553,9 @@ linux_nat_add_target (struct target_ops *t)
 
   add_target (t);
 
+  /* Point out that this target support record wait. */
+  t->to_support_record_wait = 1;
+
   /* TODO: Eliminate this and have libthread_db use
      find_target_beneath.  */
   thread_db_init (t);
index dc7c55e87a4d1ea4b57747079592f1172068d453..c7a8acb62652987ba5adf5b76df0fc76517b755b 100644 (file)
@@ -45,7 +45,6 @@ static int record_insn_num = 0;
 struct target_ops record_ops;
 int record_resume_step = 0;
 enum exec_direction_kind record_execdir = EXEC_FORWARD;
-int record_linux_async_permitted = 0;
 static int record_get_sig = 0;
 static sigset_t record_maskall;
 static int record_not_record = 0;
@@ -395,7 +394,7 @@ record_open (char *name, int from_tty)
     {
       error (_("Record: record target can't debug inferior in non-stop mode (non-stop)."));
     }
-  if (record_linux_async_permitted)
+  if (target_async_permitted)
     {
       error (_("Record: record target can't debug the GNU/Linux inferior in asynchronous mode (linux-async)."));
     }
index 9e20013104c05831386f1cc2fb8d06fa930751d2..174697576ae61541064a3e972287f29fcf811bcf 100644 (file)
@@ -77,7 +77,6 @@ extern struct target_ops record_ops;
 extern int record_resume_step;
 extern int record_regcache_raw_write_regnum;
 extern enum exec_direction_kind record_execdir;
-extern int record_linux_async_permitted;
 
 extern int record_arch_list_add_reg (int num);
 extern int record_arch_list_add_mem (CORE_ADDR addr, int len);