changeset 7890:73ef513855e7

dbstack fixes
author John W. Eaton <jwe@octave.org>
date Tue, 17 Jun 2008 13:58:21 -0400
parents 76142609e8d2
children 0280a546622c
files src/ChangeLog src/debug.cc src/pt-stmt.cc src/toplev.cc src/toplev.h
diffstat 5 files changed, 121 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/src/ChangeLog	Fri Jun 13 13:55:16 2008 -0400
+++ b/src/ChangeLog	Tue Jun 17 13:58:21 2008 -0400
@@ -1,3 +1,16 @@
+2008-06-17  John W. Eaton  <jwe@octave.org>
+
+	* toplev.h, toplev.cc (class octave_call_stack):
+	Push elements on and pop from back of queue.
+	(octave_call_stack::do_push, octave_call_stack::do_pop):
+	Always adjust curr_frame.
+	(octave_call_stack::size, octave_call_stack::do_size): New functions.
+	* pt-stmt.cc (tree_statement::eval):
+	Also call octave_call_stack::set_statement when debugging.
+	* debug.cc (push_dummy_call_stack_elt): New function.
+	(Fdbstack): Omit dbstack from call stack by popping element rather
+	than adjusting frame number.  Correctly handle arg.
+
 2008-06-12  David Bateman  <dbateman@free.fr>
 
 	* DLD-FUNCTIONS/qr.cc (Fqrupdate, Fqrinsert, Fqrshift, Fqrdelete):
--- a/src/debug.cc	Fri Jun 13 13:55:16 2008 -0400
+++ b/src/debug.cc	Tue Jun 17 13:58:21 2008 -0400
@@ -695,6 +695,12 @@
   return retval;
 }
 
+void
+push_dummy_call_stack_elt (void *)
+{
+  octave_call_stack::push (static_cast<octave_function *> (0));
+}
+
 DEFCMD (dbstack, args, nargout,
   "-*- texinfo -*-\n\
 @deftypefn {Loadable Function} {[@var{stack}, @var{idx}]} dbstack (@var{n})\n\
@@ -705,10 +711,25 @@
 {
   octave_value_list retval;
 
-  int n = 0;
+  unwind_protect::begin_frame ("Fdbstack");
+
+  // Debugging functions should not be included in the call stack, so
+  // we pop the dbstack function from the stack and then set up to
+  // restore a stack element when we exit this function (or when it is
+  // cleaned up).
+
+  octave_call_stack::pop ();
+
+  unwind_protect::add (push_dummy_call_stack_elt, 0);
+
+  size_t total_frames = octave_call_stack::size ();
+
+  size_t nframes = total_frames;
 
   if (args.length () == 1)
     {
+      int n = 0;
+
       octave_value arg = args(0);
 
       if (arg.is_string ())
@@ -719,61 +740,56 @@
 	}
       else
 	n = args(0).int_value ();
+
+      if (n > 0)
+	nframes = n;
+      else
+	error ("dbstack: expecting N to be a nonnegative integer");
     }
 
   if (! error_state)
     {
-      if (n >= 0)
-	{
-	  size_t curr_frame = octave_call_stack::current_frame ();
+      size_t curr_frame = octave_call_stack::current_frame ();
 
-	  // Skip dbstack stack frame.
-	  if (! Vdebugging)
-	    curr_frame++;
+      Octave_map stk = octave_call_stack::backtrace (nframes);
+
+      octave_idx_type idx = total_frames - curr_frame;
 
-	  // Adjust so that this is the index of where we are in the array
-	  // that is returned in retval(0).
-	  size_t idx = curr_frame - n;
-
-	  // Add one here to skip the __dbstack__ stack frame.
-	  Octave_map stk = octave_call_stack::backtrace (curr_frame + n);
+      if (nargout == 0)
+	{
+	  octave_idx_type nframes = stk.numel ();
 
-	  if (nargout == 0)
+	  if (nframes > 0)
 	    {
-	      octave_idx_type nframes = stk.numel ();
-
-	      if (nframes > 0)
-		{
-		  octave_stdout << "Stopped in:\n\n";
+	      octave_stdout << "Stopped in:\n\n";
 
-		  Cell names = stk.contents ("name");
-		  Cell lines = stk.contents ("line");
-		  Cell columns = stk.contents ("column");
-
-		  for (octave_idx_type i = 0; i < nframes; i++)
-		    {
-		      octave_value name = names(i);
-		      octave_value line = lines(i);
-		      octave_value column = columns(i);
+	      Cell names = stk.contents ("name");
+	      Cell lines = stk.contents ("line");
+	      Cell columns = stk.contents ("column");
 
-		      octave_stdout << (i == idx - 1 ? "--> " : "    ")
-				    << name.string_value ()
-				    << " at line " << line.int_value ()
-				    << " column " << column.int_value ()
-				    << std::endl;
-		    }
+	      for (octave_idx_type i = 0; i < nframes; i++)
+		{
+		  octave_value name = names(i);
+		  octave_value line = lines(i);
+		  octave_value column = columns(i);
+
+		  octave_stdout << (i == idx ? "--> " : "    ")
+				<< name.string_value ()
+				<< " at line " << line.int_value ()
+				<< " column " << column.int_value ()
+				<< std::endl;
 		}
 	    }
-	  else
-	    {
-	      retval(1) = idx;
-	      retval(0) = stk;
-	    }
 	}
       else
-	error ("dbstack: expecting N to be a nonnegative integer");
+	{
+	  retval(1) = idx < 0 ? 1 : idx + 1;
+	  retval(0) = stk;
+	}
     }
 
+  unwind_protect::run_frame ("Fdbstack");
+
   return retval;
 }
 
@@ -798,7 +814,7 @@
 
   if (! error_state)
     {
-      if (who == "dbdown")
+      if (who == "dbup")
 	n = -n;
 
       if (! octave_call_stack::goto_frame_relative (n, true))
--- a/src/pt-stmt.cc	Fri Jun 13 13:55:16 2008 -0400
+++ b/src/pt-stmt.cc	Tue Jun 17 13:58:21 2008 -0400
@@ -88,7 +88,7 @@
 
   if (cmd || expr)
     {
-      if (! (symbol_table::at_top_level () || Vdebugging))
+      if (! symbol_table::at_top_level ())
 	octave_call_stack::set_statement (this);
 
       maybe_echo_code (in_function_or_script_body);
--- a/src/toplev.cc	Fri Jun 13 13:55:16 2008 -0400
+++ b/src/toplev.cc	Tue Jun 17 13:58:21 2008 -0400
@@ -116,9 +116,11 @@
 {
   int retval = -1;
 
-  for (const_iterator p = cs.begin () + q; p != cs.end (); p++)
+  const_iterator p = cs.end ();
+
+  while (p != cs.begin ())
     {
-      const call_stack_elt& elt = *p;
+      const call_stack_elt& elt = *(--p);
 
       octave_function *f = elt.fcn;
 
@@ -142,9 +144,11 @@
 {
   int retval = -1;
 
-  for (const_iterator p = cs.begin () + q; p != cs.end (); p++)
+  const_iterator p = cs.end ();
+
+  while (p != cs.begin ())
     {
-      const call_stack_elt& elt = *p;
+      const call_stack_elt& elt = *(--p);
 
       octave_function *f = elt.fcn;
 
@@ -168,9 +172,11 @@
 {
   octave_user_script *retval = 0;
 
-  for (const_iterator p = cs.begin () + q; p != cs.end (); p++)
+  const_iterator p = cs.end ();
+
+  while (p != cs.begin ())
     {
-      const call_stack_elt& elt = *p;
+      const call_stack_elt& elt = *(--p);
 
       octave_function *f = elt.fcn;
 
@@ -189,9 +195,11 @@
 {
   octave_user_function *retval = 0;
 
-  for (const_iterator p = cs.begin () + q; p != cs.end (); p++)
+  const_iterator p = cs.end ();
+
+  while (p != cs.begin ())
     {
-      const call_stack_elt& elt = *p;
+      const call_stack_elt& elt = *(--p);
 
       octave_function *f = elt.fcn;
 
@@ -210,9 +218,11 @@
 {
   octave_user_code *retval = 0;
 
-  for (const_iterator p = cs.begin () + q; p != cs.end (); p++)
+  const_iterator p = cs.end ();
+
+  while (p != cs.begin ())
     {
-      const call_stack_elt& elt = *p;
+      const call_stack_elt& elt = *(--p);
 
       octave_function *f = elt.fcn;
 
@@ -227,13 +237,11 @@
 }
 
 Octave_map
-octave_call_stack::do_backtrace (int n) const
+octave_call_stack::do_backtrace (int nframes) const
 {
   Octave_map retval;
 
-  int nframes = cs.size () - n;
-
-  if (n >= 0 && nframes > 0)
+  if (nframes > 0 && nframes <= cs.size ())
     {
       Cell keys (6, 1);
 
@@ -251,11 +259,13 @@
       Cell scope (nframes, 1);
       Cell context (nframes, 1);
 
-      octave_idx_type k = 0;
+      octave_idx_type k = nframes - 1;
+
+      const_iterator p = cs.begin ();
 
-      for (const_iterator p = cs.begin () + n; p != cs.end (); p++)
+      while (k >= 0)
 	{
-	  const call_stack_elt& elt = *p;
+	  const call_stack_elt& elt = *p++;
 
 	  scope(k) = elt.scope;
 	  context(k) = elt.context;
@@ -292,7 +302,7 @@
 	      column(k) = -1;
 	    }
 
-	  k++;
+	  k--;
 	}
 
       retval.assign ("file", file);
@@ -354,9 +364,13 @@
 
   if (n == 0)
     retval = true;
-  else if ((n > 0 && static_cast<size_t> (n) < sz - curr_frame)
-	   || (n < 0 && static_cast<size_t> (-n) < curr_frame))
-    retval = goto_frame (curr_frame + n, verbose);
+  else
+    {
+      size_t frame = static_cast<size_t> (n) + curr_frame;
+
+      if ((n > 0 && frame < sz) || (n < 0 && frame >= 0))
+	retval = goto_frame (frame, verbose);
+    }
 
   return retval;
 }
--- a/src/toplev.h	Fri Jun 13 13:55:16 2008 -0400
+++ b/src/toplev.h	Tue Jun 17 13:58:21 2008 -0400
@@ -154,6 +154,11 @@
     return instance_ok () ? instance->do_current_frame () : 0;
   }
 
+  static size_t size (void)
+  {
+    return instance_ok () ? instance->do_size () : 0;
+  }
+
   // Function at location N on the call stack (N == 0 is current), may
   // be built-in.
   static octave_function *element (size_t n)
@@ -255,6 +260,8 @@
 
   size_t do_current_frame (void) { return curr_frame; }
 
+  size_t do_size (void) { return cs.size (); }
+
   octave_function *do_element (size_t n)
   {
     octave_function *retval = 0;
@@ -277,10 +284,9 @@
   void do_push (octave_function *f, symbol_table::scope_id scope,
 		symbol_table::context_id context)
   {
-    if (Vdebugging)
-      curr_frame++;
+    curr_frame++;
 
-    cs.push_front (call_stack_elt (f, scope, context));
+    cs.push_back (call_stack_elt (f, scope, context));
   }
 
   octave_function *do_top (void) const
@@ -289,7 +295,7 @@
 
     if (! cs.empty ())
       {
-	const call_stack_elt& elt = cs.front ();
+	const call_stack_elt& elt = cs.back ();
 	retval = elt.fcn;
       }
 
@@ -302,7 +308,7 @@
 
     if (! cs.empty ())
       {
-	const call_stack_elt& elt = cs.front ();
+	const call_stack_elt& elt = cs.back ();
 	retval = elt.stmt;
       }
 
@@ -313,7 +319,8 @@
   {
     if (! cs.empty ())
       {
-	call_stack_elt& elt = cs.front ();
+	call_stack_elt& elt = cs.back ();
+
 	elt.stmt = s;
       }
   }
@@ -328,10 +335,9 @@
   {
     if (! cs.empty ())
       {
-	if (Vdebugging)
-	  curr_frame--;
+	curr_frame--;
 
-	cs.pop_front ();
+	cs.pop_back ();
       }
   }