4 """Control of and utilities for debugging.""" |
4 """Control of and utilities for debugging.""" |
5 |
5 |
6 import inspect |
6 import inspect |
7 import os |
7 import os |
8 import sys |
8 import sys |
|
9 |
|
10 from coverage.misc import isolate_module |
|
11 |
|
12 os = isolate_module(os) |
9 |
13 |
10 |
14 |
11 # When debugging, it can be helpful to force some options, especially when |
15 # When debugging, it can be helpful to force some options, especially when |
12 # debugging the configuration mechanisms you usually use to control debugging! |
16 # debugging the configuration mechanisms you usually use to control debugging! |
13 # This is a list of forced debugging options. |
17 # This is a list of forced debugging options. |
36 """Write a line of debug output.""" |
40 """Write a line of debug output.""" |
37 if self.should('pid'): |
41 if self.should('pid'): |
38 msg = "pid %5d: %s" % (os.getpid(), msg) |
42 msg = "pid %5d: %s" % (os.getpid(), msg) |
39 self.output.write(msg+"\n") |
43 self.output.write(msg+"\n") |
40 if self.should('callers'): |
44 if self.should('callers'): |
41 dump_stack_frames(self.output) |
45 dump_stack_frames(out=self.output) |
42 self.output.flush() |
46 self.output.flush() |
43 |
47 |
44 def write_formatted_info(self, header, info): |
48 def write_formatted_info(self, header, info): |
45 """Write a sequence of (label,data) pairs nicely.""" |
49 """Write a sequence of (label,data) pairs nicely.""" |
46 self.write(info_header(header)) |
50 self.write(info_header(header)) |
74 prefix = "" |
78 prefix = "" |
75 else: |
79 else: |
76 yield "%*s: %s" % (label_len, label, data) |
80 yield "%*s: %s" % (label_len, label, data) |
77 |
81 |
78 |
82 |
79 def short_stack(): # pragma: debugging |
83 def short_stack(limit=None): # pragma: debugging |
80 """Return a string summarizing the call stack. |
84 """Return a string summarizing the call stack. |
81 |
85 |
82 The string is multi-line, with one line per stack frame. Each line shows |
86 The string is multi-line, with one line per stack frame. Each line shows |
83 the function name, the file name, and the line number: |
87 the function name, the file name, and the line number: |
84 |
88 |
86 start_import_stop : /Users/ned/coverage/trunk/tests/coveragetest.py @95 |
90 start_import_stop : /Users/ned/coverage/trunk/tests/coveragetest.py @95 |
87 import_local_file : /Users/ned/coverage/trunk/tests/coveragetest.py @81 |
91 import_local_file : /Users/ned/coverage/trunk/tests/coveragetest.py @81 |
88 import_local_file : /Users/ned/coverage/trunk/coverage/backward.py @159 |
92 import_local_file : /Users/ned/coverage/trunk/coverage/backward.py @159 |
89 ... |
93 ... |
90 |
94 |
|
95 `limit` is the number of frames to include, defaulting to all of them. |
|
96 |
91 """ |
97 """ |
92 stack = inspect.stack()[:0:-1] |
98 stack = inspect.stack()[limit:0:-1] |
93 return "\n".join("%30s : %s @%d" % (t[3], t[1], t[2]) for t in stack) |
99 return "\n".join("%30s : %s @%d" % (t[3], t[1], t[2]) for t in stack) |
94 |
100 |
95 |
101 |
96 def dump_stack_frames(out=None): # pragma: debugging |
102 def dump_stack_frames(limit=None, out=None): # pragma: debugging |
97 """Print a summary of the stack to stdout, or some place else.""" |
103 """Print a summary of the stack to stdout, or some place else.""" |
98 out = out or sys.stdout |
104 out = out or sys.stdout |
99 out.write(short_stack()) |
105 out.write(short_stack(limit=limit)) |
100 out.write("\n") |
106 out.write("\n") |