##// END OF EJS Templates
util: introduce util.debugstacktrace for showing a stack trace without crashing...
Mads Kiilerich -
r20244:47d08436 default
parent child Browse files
Show More
@@ -7,21 +7,12 b' traceback printed to stderr.'
7 This currently only checks store locks, not working copy locks.
7 This currently only checks store locks, not working copy locks.
8 """
8 """
9 import os
9 import os
10 import traceback
10 from mercurial import util
11
12 def _warnstack(ui, msg, skip=1):
13 '''issue warning with the message and the current stack, skipping the
14 skip last entries'''
15 ui.warn('%s at:\n' % msg)
16 entries = traceback.extract_stack()[:-skip]
17 fnmax = max(len(entry[0]) for entry in entries)
18 for fn, ln, func, _text in entries:
19 ui.warn(' %*s:%-4s in %s\n' % (fnmax, fn, ln, func))
20
11
21 def _checklock(repo):
12 def _checklock(repo):
22 l = repo._lockref and repo._lockref()
13 l = repo._lockref and repo._lockref()
23 if l is None or not l.held:
14 if l is None or not l.held:
24 _warnstack(repo.ui, 'missing lock', skip=2)
15 util.debugstacktrace('missing lock', skip=1)
25
16
26 def reposetup(ui, repo):
17 def reposetup(ui, repo):
27 orig = repo.__class__
18 orig = repo.__class__
@@ -1983,3 +1983,20 b' class hooks(object):'
1983 self._hooks.sort(key=lambda x: x[0])
1983 self._hooks.sort(key=lambda x: x[0])
1984 for source, hook in self._hooks:
1984 for source, hook in self._hooks:
1985 hook(*args)
1985 hook(*args)
1986
1987 def debugstacktrace(msg='stacktrace', skip=0, f=sys.stderr):
1988 '''Writes a message to f (stderr) with a nicely formatted stacktrace.
1989 Skips the 'skip' last entries.
1990 It can be used everywhere and do intentionally not require an ui object.
1991 Not be used in production code but very convenient while developing.
1992 '''
1993 f.write('%s at:\n' % msg)
1994 entries = [('%s:%s' % (fn, ln), func)
1995 for fn, ln, func, _text in traceback.extract_stack()[:-skip - 1]]
1996 if entries:
1997 fnmax = max(len(entry[0]) for entry in entries)
1998 for fnln, func in entries:
1999 f.write(' %-*s in %s\n' % (fnmax, fnln, func))
2000
2001 # convenient shortcut
2002 dst = debugstacktrace
@@ -23,3 +23,25 b''
23 uncompressed data size (min/max/avg) : 43 / 43 / 43
23 uncompressed data size (min/max/avg) : 43 / 43 / 43
24 full revision size (min/max/avg) : 44 / 44 / 44
24 full revision size (min/max/avg) : 44 / 44 / 44
25 delta size (min/max/avg) : 0 / 0 / 0
25 delta size (min/max/avg) : 0 / 0 / 0
26
27
28 Test internal debugstacktrace command
29
30 $ cat > debugstacktrace.py << EOF
31 > from mercurial.util import debugstacktrace, dst, sys
32 > def f():
33 > dst('hello world')
34 > def g():
35 > f()
36 > debugstacktrace(skip=-5, f=sys.stdout)
37 > g()
38 > EOF
39 $ python debugstacktrace.py
40 hello world at:
41 debugstacktrace.py:7 in <module>
42 debugstacktrace.py:5 in g
43 debugstacktrace.py:3 in f
44 stacktrace at:
45 debugstacktrace.py:7 *in <module> (glob)
46 debugstacktrace.py:6 *in g (glob)
47 */util.py:* in debugstacktrace (glob)
General Comments 0
You need to be logged in to leave comments. Login now