Showing posts with label pdb. Show all posts
Showing posts with label pdb. Show all posts

Thursday, November 28, 2013

Solution: To change a local variable in Pdb

In the previous post, I had mentioned the problem. This is happening because the cache of the current frame gets  overridden by the contents of the real locals which undoes modifications made by the debugging user.

To have a solution for this issue, you need to make changes in your installed python package. Here are the steps.
Note: This change will be effective for Python 2.4 version(Tested with this version only)
1.  Login your mach as a root user.
2.  cd /usr/lib
3.  chmod 777 python2.4/pdb.py
4.  cp python2.4/pdb.py YOUR_BACKUP_LOC (Do not forget to have a backup of this file. We are going to make changes in this file)
5.  Make changes in /usr/lib/python2.4/pdb.py as said below.
6.  chmod 755  python2.4/pdb.py

Changeset for pdb.py.

--- a/Lib/pdb.py
+++ b/Lib/pdb.py
@@ -114,6 +118,10 @@ class Pdb(bdb.Bdb, cmd.Cmd):
 def setup(self, f, t):
        self.forget()
        self.stack, self.curindex = self.get_stack(f, t)
        self.curframe = self.stack[self.curindex][0]
+       # The f_locals dictionary is updated from the actual frame
+       # locals whenever the .f_locals accessor is called, so we
+       # cache it here to ensure that modifications are not overwritten.
+       self.curframe_locals = self.curframe.f_locals
        self.execRcLines()

@@ -202,7 +210,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
     def default(self, line):
         if line[:1] == '!': line = line[1:]
-        locals = self.curframe.f_locals
+       locals = self.curframe_locals
         globals = self.curframe.f_globals
         try:
             code = compile(line + '\n', '<stdin>', 'single')

@@ -360,7 +368,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
      def do_break(self, arg, temporary = 0):
                 .........
                 .........
                 try:
                     func = eval(arg,
                                 self.curframe.f_globals,
-                                self.curframe.f_locals)
+                               self.curframe_locals)
                 except:
                     func = arg
                 try:

@@ -681,7 +689,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
     def do_debug(self, arg):
         sys.settrace(None)
         globals = self.curframe.f_globals
-        locals = self.curframe.f_locals
+       locals = self.curframe_locals
         p = Pdb(self.completekey, self.stdin, self.stdout)
         p.prompt = "(%s) " % self.prompt.strip()
         print >>self.stdout, "ENTERING RECURSIVE DEBUGGER"

@@ -705,9 +713,8 @@ class Pdb(bdb.Bdb, cmd.Cmd):
    def do_args(self, arg):
-        f = self.curframe
-        co = f.f_code
-        dict = f.f_locals

+       co = self.curframe.f_code
+       dict = self.curframe_locals

         n = co.co_argcount
         if co.co_flags & 4: n = n+1
         if co.co_flags & 8: n = n+1

@@ -719,8 +726,8 @@ class Pdb(bdb.Bdb, cmd.Cmd):
     def do_retval(self, arg):
-        if '__return__' in self.curframe.f_locals:
-            print >>self.stdout, self.curframe.f_locals['__return__']

+       if '__return__' in self.curframe_locals:
+           print >>self.stdout, self.curframe_locals['__return__']

         else:
             print >>self.stdout, '*** Not yet returned!'
     do_rv = do_retval

@@ -728,7 +735,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
     def _getval(self, arg):
         try:
             return eval(arg, self.curframe.f_globals,
-                        self.curframe.f_locals)
+                       self.curframe_locals)
         except:
             t, v = sys.exc_info()[:2]
             if isinstance(t, str):

@@ -797,7 +804,7 @@ class Pdb(bdb.Bdb, cmd.Cmd):
     def do_whatis(self, arg):
         try:
             value = eval(arg, self.curframe.f_globals,
-                            self.curframe.f_locals)
+                           self.curframe_locals)
         except:
             t, v = sys.exc_info()[:2]
             if type(t) == type(''):

Note: This is not exactly a changeSet. You need to manually modify the code. Red code is existing code and should be removed and Green code should be replaced in those places.

Wednesday, November 27, 2013

Changing a local variable in the Python debugger

I know that there is some issue with pdb debugger when you try to change a local variable.
But while trying to get any possible workaround, encountered this.
Have a look at it.



In the above case, local variable x has been changed in pdb mode. All I did was not to stop at any point after changing this variable.

Now look at this.


Here local variable has not been changed. Here after changing its value to "hello" all I did was to go stepwise. Even tried again to change it to "exper" but that also didn't work.

This has been a long-standing issue, dating back at least to this 2004 post on this topic.  There must be some temporary patch available for this.

Look for my new post. As soon as I find the fix, will post that here.