PDB does not allow jumping to first statement?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Chris Lasher

    PDB does not allow jumping to first statement?

    Hi all,

    I have a simple script:

    ---
    #!/usr/bin/env python

    a = 1
    b = 2

    c = a + b

    print c
    ---

    I launch said script with pdb:

    python -m pdb simple.py

    I noticed that I absolutely cannot jump back to the first statement
    (line 3, "a = 1") using the jump command. I can jump to any other line
    BUT the first statement's using the "jump <line number>" command. I
    experience the same behavior with Winpdb and rpdb2. Why is this?

    Stumped,
    Chris

  • Duncan Booth

    #2
    Re: PDB does not allow jumping to first statement?

    "Chris Lasher" <chris.lasher@g mail.comwrote:
    I noticed that I absolutely cannot jump back to the first statement
    (line 3, "a = 1") using the jump command. I can jump to any other line
    BUT the first statement's using the "jump <line number>" command. I
    experience the same behavior with Winpdb and rpdb2. Why is this?
    >
    Which version of Python, and what happens when you try it?

    It works fine for me with Python 2.5 on Windows:

    C:\Temp>\python 25\python -m pdb t.py
    c:\temp\t.py(3) <module>()
    -a = 1
    (Pdb) s
    c:\temp\t.py(4) <module>()
    -b = 2
    (Pdb) j 3
    c:\temp\t.py(3) <module>()
    -a = 1
    (Pdb)

    Comment

    • Peter Otten

      #3
      Re: PDB does not allow jumping to first statement?

      Duncan Booth wrote:
      "Chris Lasher" <chris.lasher@g mail.comwrote:
      >
      >I noticed that I absolutely cannot jump back to the first statement
      >(line 3, "a = 1") using the jump command. I can jump to any other line
      >BUT the first statement's using the "jump <line number>" command. I
      >experience the same behavior with Winpdb and rpdb2. Why is this?
      >>
      >
      Which version of Python, and what happens when you try it?
      >
      It works fine for me with Python 2.5 on Windows:
      >
      C:\Temp>\python 25\python -m pdb t.py
      >c:\temp\t.py(3 )<module>()
      -a = 1
      (Pdb) s
      >c:\temp\t.py(4 )<module>()
      -b = 2
      (Pdb) j 3
      >c:\temp\t.py(3 )<module>()
      -a = 1
      (Pdb)
      It looks like you successfully jumped to the first line, but it will be
      skipped if you try to execute it:

      $ cat tmp.py
      print "aaa"
      print "bbb"
      print "ccc"
      print "ddd"
      $ python2.5 -m pdb tmp.py
      /home/nn/tmp.py(1)<modul e>()
      -print "aaa"
      (Pdb) s
      aaa
      /home/nn/tmp.py(2)<modul e>()
      -print "bbb"
      (Pdb) j 1
      /home/nn/tmp.py(1)<modul e>()
      -print "aaa"
      (Pdb) s
      bbb <-- wrong
      /home/nn/tmp.py(3)<modul e>()
      -print "ccc"
      (Pdb) s
      ccc
      /home/nn/tmp.py(4)<modul e>()
      -print "ddd"
      (Pdb) j 2
      /home/nn/tmp.py(2)<modul e>()
      -print "bbb"
      (Pdb) s
      bbb <-- correct
      /home/nn/tmp.py(3)<modul e>()
      -print "ccc"

      Peter

      Comment

      • Duncan Booth

        #4
        Re: PDB does not allow jumping to first statement?

        Peter Otten <__peter__@web. dewrote:
        >Which version of Python, and what happens when you try it?
        >>
        >It works fine for me with Python 2.5 on Windows:
        >>
        >C:\Temp>\pytho n25\python -m pdb t.py
        >>c:\temp\t.py( 3)<module>()
        >-a = 1
        >(Pdb) s
        >>c:\temp\t.py( 4)<module>()
        >-b = 2
        >(Pdb) j 3
        >>c:\temp\t.py( 3)<module>()
        >-a = 1
        >(Pdb)
        >
        It looks like you successfully jumped to the first line, but it will
        be
        skipped if you try to execute it:
        >
        That's why I asked what actually happened. Yes, you and the OP seem to
        be correct, jumping to the first executable line in a module appears not
        to execute the line.

        I verified (with a print statement in pdb) that assigning to
        self.curframe.f _lineno sets self.curframe.f _lineno and
        sel.curframe.f_ lasti incorrectly:

        C:\Temp>\python 25\python -m pdb t.py
        c:\temp\t.py(3) <module>()
        -a = 1
        (Pdb) s
        c:\temp\t.py(4) <module>()
        -b = 2
        (Pdb) s
        c:\temp\t.py(5) <module>()
        -a = 3
        (Pdb) l
        1 #!/usr/bin/env python
        2
        3 a = 1
        4 b = 2
        5 -a = 3
        6 c = a + b
        7 import dis, sys
        8 dis.dis(sys._ge tframe().f_code )
        9 print c
        [EOF]
        (Pdb) j 4
        f_lineno 4 f_lasti 6
        c:\temp\t.py(4) <module>()
        -b = 2
        (Pdb) j 3
        f_lineno 4 f_lasti 6
        c:\temp\t.py(3) <module>()
        -a = 1
        (Pdb) j 5
        f_lineno 5 f_lasti 12
        c:\temp\t.py(5) <module>()
        -a = 3
        (Pdb) j 3
        f_lineno 4 f_lasti 6
        c:\temp\t.py(3) <module>()
        -a = 1
        (Pdb)

        The problem looks to be in frameobject.c:

        addr = 0;
        line = f->f_code->co_firstlineno ;
        new_lasti = -1;
        for (offset = 0; offset < lnotab_len; offset += 2) {
        addr += lnotab[offset];
        line += lnotab[offset+1];
        if (line >= new_lineno) {
        new_lasti = addr;
        new_lineno = line;
        break;
        }
        }

        The first bytes in lnotab are the length and line increment for line 3
        (i.e. 6, 1). If line==f->f_code->co_firstline no it should set new_lasti=
        0, new_lineno=line but the loop still executes once which increments
        new_lasti and new_lineno to the next line (6, 4).


        Comment

        • rocky.bernstein@gmail.com

          #5
          Re: PDB does not allow jumping to first statement?

          On Mar 26, 6:06 pm, "Chris Lasher" <chris.las...@g mail.comwrote:
          Hi all,
          >
          I have a simple script:
          >
          ---
          #!/usr/bin/envpython
          >
          a = 1
          b = 2
          >
          c = a + b
          >
          print c
          ---
          >
          I launch said script withpdb:
          >
          python-mpdbsimple.py
          >
          I noticed that I absolutely cannot jump back to the first statement
          (line 3, "a = 1") using the jump command. I can jump to any other line
          BUT the first statement's using the "jump <line number>" command. I
          experience the same behavior with Winpdb and rpdb2. Why is this?
          >
          Stumped,
          Chris
          I tried on GNU/Linux and Python versions 2.4 and 2.5 and get the same
          behavior. Best as I can tell, it looks like a bug in Python. pdb,
          pydb, rpdb2 all handle the "jump" command by changing the frame
          f_lineno value. When the corresponding code pointer has offset 0 (or
          equivalently and more simlply as you put it, is the first statement)
          this doesn't seem to work properly. But this also implies that all you
          need to do is add something as the first statement. A docstring
          comment, e.g.
          "this is what my program does..."
          comes to mind :-)

          Lastly, I'll mention that I what most folks want to do is not jump to
          the beginning of the program but rather *restart* it. The difference
          here as applied to your example is seen in the way variables (e.g. a,
          b, and c) are handled. In a "restart", those names would go back to
          being undefined and referring to them before assigning to them would
          cause a NameError exception. With "jump", they retain their existing
          values.

          In pydb (http://bashdb.sf.net/pydb) there are two variations of
          restarting a program, one which preserves debugger state ("run") and
          one which doesn't ("restart") as it is just a re-exec of the program.
          In the presence of multiple threads the exec restart the only reliable
          way I know of to force a restart.

          Recently in Python's SVN the patch I submitted over a year ago was
          applied, so if you prefer pdb and want the "run"-like restart, you can
          use that.

          Comment

          • Chris Lasher

            #6
            Re: PDB does not allow jumping to first statement?

            On Mar 27, 5:59 am, "rocky.bernst.. .@gmail.com"
            <rocky.bernst.. .@gmail.comwrot e:
            I tried on GNU/Linux and Python versions 2.4 and 2.5 and get the same
            behavior. Best as I can tell, it looks like a bug in Python. pdb,
            pydb, rpdb2 all handle the "jump" command by changing the frame
            f_lineno value. When the corresponding code pointer has offset 0 (or
            equivalently and more simlply as you put it, is the first statement)
            this doesn't seem to work properly. But this also implies that all you
            need to do is add something as the first statement. A docstring
            comment, e.g.
            "this is what my program does..."
            comes to mind :-)
            I started implementing this, but it's a hack. Looks like it's time for
            me to file a bug report!
            Lastly, I'll mention that I what most folks want to do is not jump to
            the beginning of the program but rather *restart* it. The difference
            here as applied to your example is seen in the way variables (e.g. a,
            b, and c) are handled. In a "restart", those names would go back to
            being undefined and referring to them before assigning to them would
            cause a NameError exception. With "jump", they retain their existing
            values.
            In the case I was working with, I really did want to "jump" and retain
            the values, rather than restart and clear those values.

            Just as an aside, Rocky, I really like your ShowMeDo on pydb. Thanks
            for making that. (For those who haven't seen it, check out the
            "Introducin g the pydb Debugger" at <http://showmedo.com/videos/Python>)

            Comment

            • Chris Lasher

              #7
              Re: PDB does not allow jumping to first statement?

              I have submitted this as a bug via SourceForge:
              <https://sourceforge.net/tracker/?
              func=detail&ati d=105470&aid=16 89458&group_id= 5470>
              or if munged
              <http://tinyurl.com/2nwxsf>

              The Python folks would like a test case and/or a patch. This is well
              beyond my ken as a humble Python user. Could anybody more
              knowledgeable please contribute one or both? Duncan or Rocky, would
              you be able to spare time and effort?

              Chris

              Comment

              • rocky.bernstein@gmail.com

                #8
                Re: PDB does not allow jumping to first statement?

                On Mar 28, 6:05 pm, "Chris Lasher" <chris.las...@g mail.comwrote:
                I have submitted this as a bug via SourceForge:
                <https://sourceforge.net/tracker/?
                func=detail&ati d=105470&aid=16 89458&group_id= 5470>
                or if munged
                <http://tinyurl.com/2nwxsf>
                >
                ThePythonfolks would like a test case and/or a patch. This is well
                beyond my ken as a humblePythonuse r. Could anybody more
                knowledgeable please contribute one or both? Duncan or Rocky, would
                you be able to spare time and effort?
                >
                Chris
                First and foremost, thanks for submitting the bug report!

                Alas, I don't use Python much anymore in day-to-day activities. Ruby
                rules! However some weekend (when I'm not doing work) I'll try to find
                time to conjure up an example.

                But here's a sketch of how I think a small test case would work. One
                would use sys.settrace() to set up the mechanism to get the current
                frame after each statement gets run. In the function, say bugcheck(),
                which used as the hook given to sys.settrace(), if the caller's
                f_lineno is not the first statement, one would set it to the first
                statement noting that the reassignment has happened so we don't loop
                indefinitely. Then one would return from the function which will let
                the program do a step and check what value of f_lineno appears in the
                subsequent calls of bugcheck().

                Alternatively one could write a .pdbrc which basically issues the
                "step" and "jump" commands and prints out the line number. (In pydb or
                gdb the command to print the current line would be "info line"; in
                pdb I'm not sure what the best command is - "list"?, "bt?

                Comment

                Working...