Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

incorrect line numbers in backtrace after removing a trace function #61479

Closed
xdegaye mannequin opened this issue Feb 22, 2013 · 9 comments
Closed

incorrect line numbers in backtrace after removing a trace function #61479

xdegaye mannequin opened this issue Feb 22, 2013 · 9 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@xdegaye
Copy link
Mannequin

xdegaye mannequin commented Feb 22, 2013

BPO 17277
Nosy @jcea, @atsuoishimoto, @abalkin, @xdegaye, @phmc
Files
  • tracer.py
  • generator.py
  • backtrace_lno.patch
  • traced_frame.patch
  • lineno_getter.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = None
    created_at = <Date 2013-02-22.16:42:49.093>
    labels = ['interpreter-core', 'type-bug']
    title = 'incorrect line numbers in backtrace after removing a trace function'
    updated_at = <Date 2017-12-20.08:56:12.397>
    user = 'https://github.com/xdegaye'

    bugs.python.org fields:

    activity = <Date 2017-12-20.08:56:12.397>
    actor = 'ishimoto'
    assignee = 'none'
    closed = False
    closed_date = None
    closer = None
    components = ['Interpreter Core']
    creation = <Date 2013-02-22.16:42:49.093>
    creator = 'xdegaye'
    dependencies = []
    files = ['29162', '29163', '29170', '29222', '35915']
    hgrepos = []
    issue_num = 17277
    keywords = ['patch']
    message_count = 8.0
    messages = ['182672', '182710', '182746', '182867', '182879', '182955', '222620', '246274']
    nosy_count = 6.0
    nosy_names = ['jcea', 'ishimoto', 'belopolsky', 'nikratio', 'xdegaye', 'pconnell']
    pr_nums = []
    priority = 'normal'
    resolution = None
    stage = None
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue17277'
    versions = ['Python 2.7', 'Python 3.3', 'Python 3.4']

    @xdegaye
    Copy link
    Mannequin Author

    xdegaye mannequin commented Feb 22, 2013

    It seems that using f_trace in the f_lineno getter PyFrame_GetLineNumber(), as
    the condition to decide when tracing is active, is incorrect.
    See the following two examples.

    In the backtrace printed by tracer.py running with python 3.3,
    the last entry should be line 12 instead of line 10:

    $ python3 /tmp/tracer.py
    Traceback (most recent call last):
      File "/tmp/tracer.py", line 15, in <module>
        foo()
      File "/tmp/tracer.py", line 10, in foo
        bar()
    ZeroDivisionError: division by zero

    This simple case does not occur with pdb, because pdb takes care of deleting
    the f_trace attribute of all the frames in the call stack when removing the
    trace function (see set_continue() in bdb.py). But this is not good enough when
    a generator is involved as can be seen when running generator.py. In the
    backtrace the last entry should be line 6 instead of line 8:

    $ python3 /tmp/generator.py
    > /tmp/generator.py(16)<module>()
    -> foo()
    (Pdb) step
    --Call--
    > /tmp/generator.py(10)foo()
    -> def foo():
    (Pdb) step
    > /tmp/generator.py(11)foo()
    -> it = gen()
    (Pdb) step
    > /tmp/generator.py(12)foo()
    -> next(it)
    (Pdb) step
    --Call--
    > /tmp/generator.py(3)gen()
    -> def gen():
    (Pdb) return
    --Return--
    > /tmp/generator.py(8)gen()->0
    -> yield i
    (Pdb) step
    > /tmp/generator.py(13)foo()
    -> next(it)
    (Pdb) continue
    Traceback (most recent call last):
      File "/tmp/generator.py", line 16, in <module>
        foo()
      File "/tmp/generator.py", line 13, in foo
        next(it)
      File "/tmp/generator.py", line 8, in gen
        yield i
    ZeroDivisionError: division by zero

    It seems that it could be possible to fix this issue by replacing the test for
    f->f_trace in PyFrame_GetLineNumber, by a test for f->f_tstate->use_tracing,
    and updating accordingly the f_lineno and f_trace setters.

    @xdegaye xdegaye mannequin added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error labels Feb 22, 2013
    @jcea
    Copy link
    Member

    jcea commented Feb 23, 2013

    Xavier, could you possibly provide a patch and a test?

    @xdegaye
    Copy link
    Mannequin Author

    xdegaye mannequin commented Feb 23, 2013

    The patch (on the default branch) reverts one of the changes made in r72488 to
    introduce the new PyFrame_GetLineNumber() function (bpo-5954): tb_lineno is
    now back again the result of the call to PyCode_Addr2Line() instead of the
    call to PyFrame_GetLineNumber().

    The other changes made by r72488 in _warnings.c and ceval.c should also
    probably be reverted as well.

    The patch updates bdb set_continue() for consistency.

    The patch adds a test to test_sys_settrace.

    @xdegaye
    Copy link
    Mannequin Author

    xdegaye mannequin commented Feb 24, 2013

    The proposed patch fixes the backtrace line numbers issue, but it does not fix
    PyFrame_GetLineNumber() which is the recommended way to get the frame line
    number.

    As mentionned in the original message, testing for f->f_trace to implement the
    f_lineno getter is not correct. The f_lineno setter is also wrong in allowing to
    modify f_lineno when the frame is not the one that is being traced (pdb prevents
    that to happen though, in do_jump()).

    I am working on another patch that should fix the issue by changing
    PyFrame_GetLineNumber() and the f_lineno accessors.

    @xdegaye
    Copy link
    Mannequin Author

    xdegaye mannequin commented Feb 24, 2013

    fix the issue by changing PyFrame_GetLineNumber() and the f_lineno accessors

    The new patch named traced_frame.patch has been uploaded.

    Also, now it is not allowed anymore to set the f_lineno attribute of a frame
    that is not the frame being traced, as f_lasti is invalidated anyway on
    returning to the evaluation of that frame.

    @xdegaye
    Copy link
    Mannequin Author

    xdegaye mannequin commented Feb 25, 2013

    The traced_frame.patch fixes also bpo-7238 and bpo-16482.

    @xdegaye
    Copy link
    Mannequin Author

    xdegaye mannequin commented Jul 9, 2014

    The previous patch changed a field in the PyThreadState structure. This new patch is simpler and does not prevent to change f_lineno when it is not the attribute of the frame being traced. The new patch fixes also bpo-7238, bpo-16482 and bpo-17697.

    @xdegaye
    Copy link
    Mannequin Author

    xdegaye mannequin commented Jul 4, 2015

    The patch is wrong, the frame may not be run by the current PyThreadState.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    @gaogaotiantian
    Copy link
    Member

    This seems to be already fixed. I can't reproduce with 3.13. Close for done.

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    2 participants