[PATCH v2] util: introduce util.debugstacktrace for showing a stack trace without crashing
Augie Fackler
raf at durin42.com
Tue Jan 14 13:07:55 CST 2014
On Sun, Jan 12, 2014 at 11:28:43PM +0100, Mads Kiilerich wrote:
> # HG changeset patch
> # User Mads Kiilerich <madski at unity3d.com>
> # Date 1389565701 -3600
> # Sun Jan 12 23:28:21 2014 +0100
> # Node ID 72b1891f41b81efa6ec13f04371c2c0740f01300
> # Parent d2704c48f4176d8cd6f21d33500820d44763585c
> util: introduce util.debugstacktrace for showing a stack trace without crashing
sure, queued
>
> This is often very handy when hacking/debugging.
>
> Calling util.debugstacktrace('hey') from a place in hg will give something like:
> hey at:
> ./hg:38 in <module>
> /home/user/hgsrc/mercurial/dispatch.py:28 in run
> /home/user/hgsrc/mercurial/dispatch.py:65 in dispatch
> /home/user/hgsrc/mercurial/dispatch.py:88 in _runcatch
> /home/user/hgsrc/mercurial/dispatch.py:740 in _dispatch
> /home/user/hgsrc/mercurial/dispatch.py:514 in runcommand
> /home/user/hgsrc/mercurial/dispatch.py:830 in _runcommand
> /home/user/hgsrc/mercurial/dispatch.py:801 in checkargs
> /home/user/hgsrc/mercurial/dispatch.py:737 in <lambda>
> /home/user/hgsrc/mercurial/util.py:472 in check
> ...
>
> diff --git a/contrib/lock-checker.py b/contrib/lock-checker.py
> --- a/contrib/lock-checker.py
> +++ b/contrib/lock-checker.py
> @@ -7,21 +7,12 @@ traceback printed to stderr.
> This currently only checks store locks, not working copy locks.
> """
> import os
> -import traceback
> -
> -def _warnstack(ui, msg, skip=1):
> - '''issue warning with the message and the current stack, skipping the
> - skip last entries'''
> - ui.warn('%s at:\n' % msg)
> - entries = traceback.extract_stack()[:-skip]
> - fnmax = max(len(entry[0]) for entry in entries)
> - for fn, ln, func, _text in entries:
> - ui.warn(' %*s:%-4s in %s\n' % (fnmax, fn, ln, func))
> +from mercurial import util
>
> def _checklock(repo):
> l = repo._lockref and repo._lockref()
> if l is None or not l.held:
> - _warnstack(repo.ui, 'missing lock', skip=2)
> + util.debugstacktrace('missing lock', skip=1)
>
> def reposetup(ui, repo):
> orig = repo.__class__
> diff --git a/mercurial/util.py b/mercurial/util.py
> --- a/mercurial/util.py
> +++ b/mercurial/util.py
> @@ -1983,3 +1983,20 @@ class hooks(object):
> self._hooks.sort(key=lambda x: x[0])
> for source, hook in self._hooks:
> hook(*args)
> +
> +def debugstacktrace(msg='stacktrace', skip=0, f=sys.stderr):
> + '''Writes a message to f (stderr) with a nicely formatted stacktrace.
> + Skips the 'skip' last entries.
> + It can be used everywhere and do intentionally not require an ui object.
> + Not be used in production code but very convenient while developing.
> + '''
> + f.write('%s at:\n' % msg)
> + entries = [('%s:%s' % (fn, ln), func)
> + for fn, ln, func, _text in traceback.extract_stack()[:-skip - 1]]
> + if entries:
> + fnmax = max(len(entry[0]) for entry in entries)
> + for fnln, func in entries:
> + f.write(' %-*s in %s\n' % (fnmax, fnln, func))
> +
> +# convenient shortcut
> +dst = debugstacktrace
> diff --git a/tests/test-debugcommands.t b/tests/test-debugcommands.t
> --- a/tests/test-debugcommands.t
> +++ b/tests/test-debugcommands.t
> @@ -23,3 +23,25 @@
> uncompressed data size (min/max/avg) : 43 / 43 / 43
> full revision size (min/max/avg) : 44 / 44 / 44
> delta size (min/max/avg) : 0 / 0 / 0
> +
> +
> +Test internal debugstacktrace command
> +
> + $ cat > debugstacktrace.py << EOF
> + > from mercurial.util import debugstacktrace, dst, sys
> + > def f():
> + > dst('hello world')
> + > def g():
> + > f()
> + > debugstacktrace(skip=-5, f=sys.stdout)
> + > g()
> + > EOF
> + $ python debugstacktrace.py
> + hello world at:
> + debugstacktrace.py:7 in <module>
> + debugstacktrace.py:5 in g
> + debugstacktrace.py:3 in f
> + stacktrace at:
> + debugstacktrace.py:7 *in <module> (glob)
> + debugstacktrace.py:6 *in g (glob)
> + */util.py:* in debugstacktrace (glob)
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
More information about the Mercurial-devel
mailing list