Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #7168 > unrolled thread
| Started by | Dun Peal <dunpealer@gmail.com> |
|---|---|
| First post | 2011-06-07 11:09 -0700 |
| Last post | 2011-06-07 23:45 -0300 |
| Articles | 7 — 5 participants |
Back to article view | Back to comp.lang.python
Function call arguments in stack trace? Dun Peal <dunpealer@gmail.com> - 2011-06-07 11:09 -0700
Re: Function call arguments in stack trace? Neil Cerutti <neilc@norwich.edu> - 2011-06-07 18:23 +0000
Re: Function call arguments in stack trace? Dun Peal <dunpealer@gmail.com> - 2011-06-07 12:31 -0700
Re: Function call arguments in stack trace? Ian Kelly <ian.g.kelly@gmail.com> - 2011-06-07 13:52 -0600
Re: Function call arguments in stack trace? Irmen de Jong <irmen.NOSPAM@xs4all.nl> - 2011-06-07 22:01 +0200
Re: Function call arguments in stack trace? Neil Cerutti <neilc@norwich.edu> - 2011-06-07 20:29 +0000
Re: Function call arguments in stack trace? "Gabriel Genellina" <gagsl-py2@yahoo.com.ar> - 2011-06-07 23:45 -0300
| From | Dun Peal <dunpealer@gmail.com> |
|---|---|
| Date | 2011-06-07 11:09 -0700 |
| Subject | Function call arguments in stack trace? |
| Message-ID | <9d344c45-8017-4c80-9a17-bc7accd81047@l26g2000yqm.googlegroups.com> |
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.
[toc] | [next] | [standalone]
| From | Neil Cerutti <neilc@norwich.edu> |
|---|---|
| Date | 2011-06-07 18:23 +0000 |
| Message-ID | <9578lmFl76U1@mid.individual.net> |
| In reply to | #7168 |
On 2011-06-07, Dun Peal <dunpealer@gmail.com> 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
[toc] | [prev] | [next] | [standalone]
| From | Dun Peal <dunpealer@gmail.com> |
|---|---|
| Date | 2011-06-07 12:31 -0700 |
| Message-ID | <6c3c9ab9-7880-4988-8258-8f8b2d4d7f72@m21g2000yqc.googlegroups.com> |
| In reply to | #7170 |
On Jun 7, 1:23 pm, Neil Cerutti <ne...@norwich.edu> 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.
[toc] | [prev] | [next] | [standalone]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2011-06-07 13:52 -0600 |
| Message-ID | <mailman.2541.1307476383.9059.python-list@python.org> |
| In reply to | #7175 |
On Tue, Jun 7, 2011 at 1:31 PM, Dun Peal <dunpealer@gmail.com> wrote: > On Jun 7, 1:23 pm, Neil Cerutti <ne...@norwich.edu> 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.
[toc] | [prev] | [next] | [standalone]
| From | Irmen de Jong <irmen.NOSPAM@xs4all.nl> |
|---|---|
| Date | 2011-06-07 22:01 +0200 |
| Message-ID | <4dee83a9$0$49174$e4fe514c@news.xs4all.nl> |
| In reply to | #7175 |
On 7-6-2011 21:31, Dun Peal wrote:
> On Jun 7, 1:23 pm, Neil Cerutti <ne...@norwich.edu> 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
[toc] | [prev] | [next] | [standalone]
| From | Neil Cerutti <neilc@norwich.edu> |
|---|---|
| Date | 2011-06-07 20:29 +0000 |
| Message-ID | <957g1rF32aU1@mid.individual.net> |
| In reply to | #7175 |
On 2011-06-07, Dun Peal <dunpealer@gmail.com> wrote:
> On Jun 7, 1:23?pm, Neil Cerutti <ne...@norwich.edu> 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
[toc] | [prev] | [next] | [standalone]
| From | "Gabriel Genellina" <gagsl-py2@yahoo.com.ar> |
|---|---|
| Date | 2011-06-07 23:45 -0300 |
| Message-ID | <mailman.12.1307500925.11593.python-list@python.org> |
| In reply to | #7168 |
En Tue, 07 Jun 2011 15:09:54 -0300, Dun Peal <dunpealer@gmail.com>
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
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web