Function call arguments in stack trace?

Discussion in 'Python' started by Dun Peal, Jun 7, 2011.

  1. Dun Peal

    Dun Peal Guest

    Hi,

    In a stack trace, is it possible to somehow get the arguments with
    which each function was called?

    So for example, if function `foo` in module `bar` was called with
    arguments `(1, [2])` when it raised an exception, then instead of:

    Traceback (most recent call last):
    File "bar.py", line 123, in foo
    build_rpms()

    The stack trace would read:

    Traceback (most recent call last):
    File "bar.py", line 123, in foo(1, [2])
    build_rpms()

    This would save a lot of debugging time!

    Thanks, D.
     
    Dun Peal, Jun 7, 2011
    #1
    1. Advertising

  2. Dun Peal

    Neil Cerutti Guest

    On 2011-06-07, Dun Peal <> wrote:
    > Hi,
    >
    > In a stack trace, is it possible to somehow get the arguments with
    > which each function was called?
    >
    > So for example, if function `foo` in module `bar` was called with
    > arguments `(1, [2])` when it raised an exception, then instead of:
    >
    > Traceback (most recent call last):
    > File "bar.py", line 123, in foo
    > build_rpms()
    >
    > The stack trace would read:
    >
    > Traceback (most recent call last):
    > File "bar.py", line 123, in foo(1, [2])
    > build_rpms()
    >
    > This would save a lot of debugging time!


    Use pdb.

    --
    Neil Cerutti
     
    Neil Cerutti, Jun 7, 2011
    #2
    1. Advertising

  3. Dun Peal

    Dun Peal Guest

    On Jun 7, 1:23 pm, Neil Cerutti <> wrote:
    > Use pdb.


    Neil, thanks for the tip; `pdb` is indeed a great debugging tool.

    Still, it doesn't obviate the need for arguments in the stack trace.
    For example:

    1) Arguments in stack trace can expedite a debugging session, and even
    obviate it completely: "Why did `foo()` fail? Oh, because it got `-1`
    as its first argument, while I only coded for positive integers!".
    2) In some environments, it's very hard to recreate a rare exception
    and analyze it with `pdb`. For instance, on a web application that
    emails the stack traces of unhandled exceptions, it's very important
    for that stack trace to be as informative as possible, since often
    that's the only debugging feedback you will get.

    Hope that makes sense, D.
     
    Dun Peal, Jun 7, 2011
    #3
  4. Dun Peal

    Ian Kelly Guest

    On Tue, Jun 7, 2011 at 1:31 PM, Dun Peal <> wrote:
    > On Jun 7, 1:23 pm, Neil Cerutti <> wrote:
    >> Use pdb.

    >
    > Neil, thanks for the tip; `pdb` is indeed a great debugging tool.
    >
    > Still, it doesn't obviate the need for arguments in the stack trace.


    Your program could use sys.excepthook to generate a custom stack trace
    for unhandled exceptions. All the stack frames are available from the
    traceback, but extracting the arguments would be tricky, and getting
    the original arguments would be impossible if they've been reassigned
    prior to the exception being raised. It would be simpler just to dump
    all the locals in the frame.
     
    Ian Kelly, Jun 7, 2011
    #4
  5. On 7-6-2011 21:31, Dun Peal wrote:
    > On Jun 7, 1:23 pm, Neil Cerutti <> wrote:
    >> Use pdb.

    >
    > Neil, thanks for the tip; `pdb` is indeed a great debugging tool.
    >
    > Still, it doesn't obviate the need for arguments in the stack trace.


    If you can't use pdb perhaps you can use the following:

    Pyro has always had a feature that prints detailed stacktraces. It is mainly meant to
    clarify stacktraces that occur on a different machine (where you don't have the option
    of using pdb), but can very well be used for normal code too:


    import sys
    import Pyro4.util
    Pyro4.config.DETAILED_TRACEBACK=True
    sys.excepthook=Pyro4.util.excepthook

    def divide(a,b):
    return a//b

    def dividebysomething(a):
    return divide(a,0)

    print dividebysomething(10)


    When you run this, this will be printed:

    [E:\projects]python trace.py
    --------------------------------------------------
    <<type 'exceptions.ZeroDivisionError'>> RAISED : integer division or modulo by zero
    Extended stacktrace follows (most recent call last)
    --------------------------------------------------
    File "trace.py", line (13), in <module>
    Source code:
    print dividebysomething(10)
    File "trace.py", line (11), in dividebysomething
    Source code:
    return divide(a,0)
    Local values:
    a = 10
    --------------------------------------------------
    File "trace.py", line (8), in divide
    Source code:
    return a//b
    Local values:
    a = 10
    b = 0
    --------------------------------------------------
    <<type 'exceptions.ZeroDivisionError'>> RAISED : integer division or modulo by zero
    --------------------------------------------------


    You can find the relevant code that produces these kinds of tracebacks in the util.py
    source file of Pyro. You can get that from Pypi:
    http://pypi.python.org/pypi/Pyro4/
    or the file directly from subversion:
    $ svn export svn://svn.razorvine.net/Pyro/Pyro4/trunk/src/Pyro4/util.py

    Perhaps you can use this or adapt it to suit your needs.


    Irmen de Jong
     
    Irmen de Jong, Jun 7, 2011
    #5
  6. Dun Peal

    Neil Cerutti Guest

    On 2011-06-07, Dun Peal <> wrote:
    > On Jun 7, 1:23?pm, Neil Cerutti <> wrote:
    >> Use pdb.

    >
    > Neil, thanks for the tip; `pdb` is indeed a great debugging
    > tool.
    >
    > Still, it doesn't obviate the need for arguments in the stack
    > trace. For example:
    >
    > 1) Arguments in stack trace can expedite a debugging session, and even
    > obviate it completely: "Why did `foo()` fail? Oh, because it got `-1`
    > as its first argument, while I only coded for positive integers!".
    > 2) In some environments, it's very hard to recreate a rare exception
    > and analyze it with `pdb`. For instance, on a web application that
    > emails the stack traces of unhandled exceptions, it's very important
    > for that stack trace to be as informative as possible, since often
    > that's the only debugging feedback you will get.
    >
    > Hope that makes sense, D.


    The locals should be in the frame object of the traceback. Here's
    a sketch of a decorator to print them out before your program
    bombs:

    import sys

    def report_arg_info(fn):
    def wrapper(*arg, **kw):
    try:
    return fn(*arg, **kw)
    except:
    frame = sys.exc_info()[2].tb_next.tb_frame
    print(frame.f_locals)
    raise
    return wrapper

    Use it as usual:

    @report_arg_info
    def my_func(bombs)
    raise ValueError

    You could log the local arguments instead.

    --
    Neil Cerutti
     
    Neil Cerutti, Jun 7, 2011
    #6
  7. En Tue, 07 Jun 2011 15:09:54 -0300, Dun Peal <>
    escribió:

    > In a stack trace, is it possible to somehow get the arguments with
    > which each function was called?
    >
    > So for example, if function `foo` in module `bar` was called with
    > arguments `(1, [2])` when it raised an exception, then instead of:
    >
    > Traceback (most recent call last):
    > File "bar.py", line 123, in foo
    > build_rpms()
    >
    > The stack trace would read:
    >
    > Traceback (most recent call last):
    > File "bar.py", line 123, in foo(1, [2])
    > build_rpms()
    >
    > This would save a lot of debugging time!


    The cgitb module does exactly that; some third-party modules offer similar
    functionality, but I don't remember any names.
    Despite its name, cgitb works with any script.

    Given this test script:

    # begin test_traceback.py
    import cgitb
    cgitb.enable(format="text")

    spam = []

    def a(x, y):
    "This is function a"
    z = x+y
    return b(z)


    def b(z, n=3):
    """This is function b.

    Its docstring is longer."""

    if n!=3:
    just(to_consume_space)

    w = c(foo=z*n)

    return w


    def c(foo=0, bar=1):
    "This is function c"
    baz = foo+bar
    spam.somenamethatdoesnotexist(foo+bar)
    anotherglobal("thatdoesnotexisteither")

    a(10, 20)
    # end test_traceback.py

    the output is:


    AttributeError
    Python 3.2: d:\apps\Python32\python.exe
    Tue Jun 7 23:36:36 2011

    A problem occurred in a Python script. Here is the sequence of
    function calls leading up to the error, in the order they occurred.

    D:\TEMP\test_traceback.py in <module>()
    27 baz = foo+bar
    28 spam.somenamethatdoesnotexist(foo+bar)
    29 anotherglobal("thatdoesnotexisteither")
    30
    31 a(10, 20)
    a = <function a>

    D:\TEMP\test_traceback.py in a(x=10, y=20)
    7 "This is function a"
    8 z = x+y
    9 return b(z)
    10
    11
    global b = <function b>
    z = 30

    D:\TEMP\test_traceback.py in b(z=30, n=3)
    18 just(to_consume_space)
    19
    20 w = c(foo=z*n)
    21
    22 return w
    w undefined
    global c = <function c>
    foo undefined
    z = 30
    n = 3

    D:\TEMP\test_traceback.py in c(foo=90, bar=1)
    26 "This is function c"
    27 baz = foo+bar
    28 spam.somenamethatdoesnotexist(foo+bar)
    29 anotherglobal("thatdoesnotexisteither")
    30
    global spam = []
    spam.somenamethatdoesnotexist undefined
    foo = 90
    bar = 1
    AttributeError: 'list' object has no attribute 'somenamethatdoesnotexist'
    [... exception attributes ...]
    [... original traceback ...]

    --
    Gabriel Genellina
     
    Gabriel Genellina, Jun 8, 2011
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Michael Borgwardt

    Empty stack trace/method call from nowhere?

    Michael Borgwardt, Sep 29, 2004, in forum: Java
    Replies:
    3
    Views:
    660
    Michael Borgwardt
    Sep 29, 2004
  2. grbgooglefan
    Replies:
    2
    Views:
    438
    Pascal Bourguignon
    Jan 30, 2008
  3. grbgooglefan
    Replies:
    4
    Views:
    458
    Kenny McCormack
    Jan 30, 2008
  4. grbgooglefan
    Replies:
    0
    Views:
    409
    grbgooglefan
    Jan 30, 2008
  5. Alok
    Replies:
    3
    Views:
    262
Loading...

Share This Page