changeset 21322:909129eb77c5

use correct stack frame when reporting debug location * toplev.h, toplev.cc (octave_call_stack::debug_user_code, octave_call_stack::debug_user_code_line, octave_call_stack::debug_user_code_column): New static functions. (octave_call_stack::do_debug_user_code, octave_call_stack::do_debug_user_code_line, octave_call_stack::do_debug_user_code_column): New member functions. * debug.cc (get_user_code): Use octave_call_stack::debug_user_code. (Fdblist): Use octave_call_stack::debug_user_code_line and octave_call_stack::debug_user_code_column. (Fdbwhere): Don't error if at top level. Improve location message. (octave_call_stack::do_goto_frame, octave_call_stack::do_goto_frame_relative): Improve location message.
author John W. Eaton <jwe@octave.org>
date Tue, 23 Feb 2016 15:05:45 -0500
parents 79a51b7e00b6
children 030d4d6c2b58
files libinterp/corefcn/debug.cc libinterp/corefcn/toplev.cc libinterp/corefcn/toplev.h
diffstat 3 files changed, 205 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/debug.cc	Mon Feb 22 21:28:22 2016 -0500
+++ b/libinterp/corefcn/debug.cc	Tue Feb 23 15:05:45 2016 -0500
@@ -180,7 +180,7 @@
   octave_user_code *dbg_fcn = 0;
 
   if (fname.empty ())
-    dbg_fcn = octave_call_stack::caller_user_code ();
+    dbg_fcn = octave_call_stack::debug_user_code ();
   else
     {
       std::string name = fname;
@@ -1506,34 +1506,34 @@
   octave_user_code *dbg_fcn = get_user_code ();
 
   if (! dbg_fcn)
-    error ("dbwhere: must be inside a user function to use dbwhere\n");
+    {
+      octave_stdout << "stopped at top level" << std::endl;
+      return ovl ();
+    }
 
   bool have_file = true;
 
-  std::string name = dbg_fcn->fcn_file_name ();
-
-  if (name.empty ())
-    {
-      have_file = false;
+  octave_stdout << "stopped in " << dbg_fcn->name () << " at ";
 
-      name = dbg_fcn->name ();
-    }
-
-  octave_stdout << "stopped in " << name << " at ";
-
-  int l = octave_call_stack::caller_user_code_line ();
+  int l = octave_call_stack::debug_user_code_line ();
 
   if (l > 0)
     {
-      octave_stdout << "line " << l << std::endl;
+      octave_stdout << "line " << l;
+
+      std::string file_name = dbg_fcn->fcn_file_name ();
 
-      if (have_file)
+      if (! file_name.empty ())
         {
-          std::string line = get_file_line (name, l);
+          octave_stdout << " [" << file_name << "]" << std::endl;
+
+          std::string line = get_file_line (file_name, l);
 
           if (! line.empty ())
             octave_stdout << l << ": " << line << std::endl;
         }
+      else
+        octave_stdout << std::endl;
     }
   else
     octave_stdout << "<unknown line>" << std::endl;
@@ -1764,7 +1764,7 @@
       name = dbg_fcn->name ();
     }
 
-  int l = octave_call_stack::caller_user_code_line ();
+  int l = octave_call_stack::debug_user_code_line ();
 
   if (l > 0)
     {
--- a/libinterp/corefcn/toplev.cc	Mon Feb 22 21:28:22 2016 -0500
+++ b/libinterp/corefcn/toplev.cc	Tue Feb 23 15:05:45 2016 -0500
@@ -185,58 +185,6 @@
   return retval;
 }
 
-int
-octave_call_stack::do_caller_user_code_line (void) const
-{
-  int retval = -1;
-
-  const_iterator p = cs.end ();
-
-  while (p != cs.begin ())
-    {
-      const stack_frame& elt = *(--p);
-
-      octave_function *f = elt.m_fcn;
-
-      if (f && f->is_user_code ())
-        {
-          if (elt.m_line > 0)
-            {
-              retval = elt.m_line;
-              break;
-            }
-        }
-    }
-
-  return retval;
-}
-
-int
-octave_call_stack::do_caller_user_code_column (void) const
-{
-  int retval = -1;
-
-  const_iterator p = cs.end ();
-
-  while (p != cs.begin ())
-    {
-      const stack_frame& elt = *(--p);
-
-      octave_function *f = elt.m_fcn;
-
-      if (f && f->is_user_code ())
-        {
-          if (elt.m_column)
-            {
-              retval = elt.m_column;
-              break;
-            }
-        }
-    }
-
-  return retval;
-}
-
 size_t
 octave_call_stack::do_num_user_code_frames
   (octave_idx_type& curr_user_frame) const
@@ -303,6 +251,148 @@
   return retval;
 }
 
+int
+octave_call_stack::do_caller_user_code_line (void) const
+{
+  int retval = -1;
+
+  const_iterator p = cs.end ();
+
+  while (p != cs.begin ())
+    {
+      const stack_frame& elt = *(--p);
+
+      octave_function *f = elt.m_fcn;
+
+      if (f && f->is_user_code ())
+        {
+          if (elt.m_line > 0)
+            {
+              retval = elt.m_line;
+              break;
+            }
+        }
+    }
+
+  return retval;
+}
+
+int
+octave_call_stack::do_caller_user_code_column (void) const
+{
+  int retval = -1;
+
+  const_iterator p = cs.end ();
+
+  while (p != cs.begin ())
+    {
+      const stack_frame& elt = *(--p);
+
+      octave_function *f = elt.m_fcn;
+
+      if (f && f->is_user_code ())
+        {
+          if (elt.m_column)
+            {
+              retval = elt.m_column;
+              break;
+            }
+        }
+    }
+
+  return retval;
+}
+
+octave_user_code *
+octave_call_stack::do_debug_user_code (void) const
+{
+  octave_user_code *retval = 0;
+
+  // This should never happen...
+  if (curr_frame == 0)
+    return retval;
+
+  // Start looking with the caller of the calling debug function.
+  size_t i = cs[curr_frame].m_prev;
+
+  while (i != 0)
+    {
+      const stack_frame& elt = cs[i];
+
+      octave_function *f = elt.m_fcn;
+
+      if (f && f->is_user_code ())
+        {
+          retval = dynamic_cast<octave_user_code *> (f);
+          break;
+        }
+    }
+
+  return retval;
+}
+
+int
+octave_call_stack::do_debug_user_code_line (void) const
+{
+  int retval = -1;
+
+  // This should never happen...
+  if (curr_frame == 0)
+    return retval;
+
+  // Start looking with the caller of the calling debug function.
+  size_t i = cs[curr_frame].m_prev;
+
+  while (i != 0)
+    {
+      const stack_frame& elt = cs[i];
+
+      octave_function *f = elt.m_fcn;
+
+      if (f && f->is_user_code ())
+        {
+          if (elt.m_line)
+            {
+              retval = elt.m_line;
+              break;
+            }
+        }
+    }
+
+  return retval;
+}
+
+int
+octave_call_stack::do_debug_user_code_column (void) const
+{
+  int retval = -1;
+
+  // This should never happen...
+  if (curr_frame == 0)
+    return retval;
+
+  // Start looking with the caller of the calling debug function.
+  size_t i = cs[curr_frame].m_prev;
+
+  while (i != 0)
+    {
+      const stack_frame& elt = cs[i];
+
+      octave_function *f = elt.m_fcn;
+
+      if (f && f->is_user_code ())
+        {
+          if (elt.m_column)
+            {
+              retval = elt.m_column;
+              break;
+            }
+        }
+    }
+
+  return retval;
+}
+
 bool
 octave_call_stack::do_all_scripts (void) const
 {
@@ -431,7 +521,9 @@
         octave_stdout << "stopped in " << elt.fcn_name ()
                       << " at line " << elt.m_line
                       << " column " << elt.m_column
-                      << " (" << elt.m_scope << "[" << elt.m_context << "])"
+                      << " [" << elt.fcn_file_name () << "] "
+                      << " (scope = " << elt.m_scope
+                      << "[context = " << elt.m_context << "])"
                       << std::endl;
     }
 
@@ -483,8 +575,10 @@
                   std::ostringstream buf;
 
                   if (f)
-                    buf << "stopped in " << f->name ()
-                        << " at line " << elt.m_line << std::endl;
+                    buf << "stopped in " << elt.fcn_name ()
+                        << " at line " << elt.m_line
+                        << " [" << elt.fcn_file_name () << "] "
+                        << std::endl;
                   else
                     buf << "at top level" << std::endl;
 
--- a/libinterp/corefcn/toplev.h	Mon Feb 22 21:28:22 2016 -0500
+++ b/libinterp/corefcn/toplev.h	Tue Feb 23 15:05:45 2016 -0500
@@ -160,18 +160,6 @@
     return instance_ok () ? instance->do_current_column () : -1;
   }
 
-  // Line in user code caller.
-  static int caller_user_code_line (void)
-  {
-    return instance_ok () ? instance->do_caller_user_code_line () : -1;
-  }
-
-  // Column in user code caller.
-  static int caller_user_code_column (void)
-  {
-    return instance_ok () ? instance->do_caller_user_code_column () : -1;
-  }
-
   // Caller function, may be built-in.
   static octave_function *caller (void)
   {
@@ -218,10 +206,40 @@
     return instance_ok () ? instance->do_element (n) : 0;
   }
 
-  // First user-defined function on the stack.
-  static octave_user_code *caller_user_code (size_t nskip = 0)
+  // User code caller.
+  static octave_user_code *caller_user_code (void)
+  {
+    return instance_ok () ? instance->do_debug_user_code () : 0;
+  }
+
+  // Line in user code caller.
+  static int caller_user_code_line (void)
+  {
+    return instance_ok () ? instance->do_caller_user_code_line () : -1;
+  }
+
+  // Column in user code caller.
+  static int caller_user_code_column (void)
   {
-    return instance_ok () ? instance->do_caller_user_code (nskip) : 0;
+    return instance_ok () ? instance->do_caller_user_code_column () : -1;
+  }
+
+  // Current function that we are debugging.
+  static octave_user_code *debug_user_code (void)
+  {
+    return instance_ok () ? instance->do_debug_user_code () : 0;
+  }
+
+  // Line number in current function that we are debugging.
+  static int debug_user_code_line (void)
+  {
+    return instance_ok () ? instance->do_debug_user_code_line () : 0;
+  }
+
+  // Column number in current function that we are debugging.
+  static int debug_user_code_column (void)
+  {
+    return instance_ok () ? instance->do_debug_user_code_column () : 0;
   }
 
   // Return TRUE if all elements on the call stack are scripts.
@@ -357,10 +375,6 @@
 
   int do_current_column (void) const;
 
-  int do_caller_user_code_line (void) const;
-
-  int do_caller_user_code_column (void) const;
-
   octave_function *do_caller (void) const
   {
     return curr_frame > 1 ? cs[curr_frame-1].m_fcn : cs[0].m_fcn;
@@ -407,6 +421,12 @@
   }
 
   octave_user_code *do_caller_user_code (size_t nskip) const;
+  int do_caller_user_code_line (void) const;
+  int do_caller_user_code_column (void) const;
+
+  octave_user_code *do_debug_user_code (void) const;
+  int do_debug_user_code_line (void) const;
+  int do_debug_user_code_column (void) const;
 
   bool do_all_scripts (void) const;