Run 'python -c SOURCE' under gdb with a breakpoint. Support injecting commands after the breakpoint is reached Returns the stdout from gdb cmds_after_breakpoint: if provided, a list of strings: gdb commands
(self, source=None, script=None,
breakpoint=BREAKPOINT_FN,
cmds_after_breakpoint=None,
import_site=False,
ignore_stderr=False)
| 157 | """Test that the debugger can debug Python.""" |
| 158 | |
| 159 | def get_stack_trace(self, source=None, script=None, |
| 160 | breakpoint=BREAKPOINT_FN, |
| 161 | cmds_after_breakpoint=None, |
| 162 | import_site=False, |
| 163 | ignore_stderr=False): |
| 164 | ''' |
| 165 | Run 'python -c SOURCE' under gdb with a breakpoint. |
| 166 | |
| 167 | Support injecting commands after the breakpoint is reached |
| 168 | |
| 169 | Returns the stdout from gdb |
| 170 | |
| 171 | cmds_after_breakpoint: if provided, a list of strings: gdb commands |
| 172 | ''' |
| 173 | # We use "set breakpoint pending yes" to avoid blocking with a: |
| 174 | # Function "foo" not defined. |
| 175 | # Make breakpoint pending on future shared library load? (y or [n]) |
| 176 | # error, which typically happens python is dynamically linked (the |
| 177 | # breakpoints of interest are to be found in the shared library) |
| 178 | # When this happens, we still get: |
| 179 | # Function "textiowrapper_write" not defined. |
| 180 | # emitted to stderr each time, alas. |
| 181 | |
| 182 | # Initially I had "--eval-command=continue" here, but removed it to |
| 183 | # avoid repeated print breakpoints when traversing hierarchical data |
| 184 | # structures |
| 185 | |
| 186 | # Generate a list of commands in gdb's language: |
| 187 | commands = [ |
| 188 | 'set breakpoint pending yes', |
| 189 | 'break %s' % breakpoint, |
| 190 | |
| 191 | # The tests assume that the first frame of printed |
| 192 | # backtrace will not contain program counter, |
| 193 | # that is however not guaranteed by gdb |
| 194 | # therefore we need to use 'set print address off' to |
| 195 | # make sure the counter is not there. For example: |
| 196 | # #0 in PyObject_Print ... |
| 197 | # is assumed, but sometimes this can be e.g. |
| 198 | # #0 0x00003fffb7dd1798 in PyObject_Print ... |
| 199 | 'set print address off', |
| 200 | |
| 201 | 'run', |
| 202 | ] |
| 203 | |
| 204 | # GDB as of 7.4 onwards can distinguish between the |
| 205 | # value of a variable at entry vs current value: |
| 206 | # http://sourceware.org/gdb/onlinedocs/gdb/Variables.html |
| 207 | # which leads to the selftests failing with errors like this: |
| 208 | # AssertionError: 'v@entry=()' != '()' |
| 209 | # Disable this: |
| 210 | if GDB_VERSION >= (7, 4): |
| 211 | commands += ['set print entry-values no'] |
| 212 | |
| 213 | if cmds_after_breakpoint: |
| 214 | if CET_PROTECTION: |
| 215 | # bpo-32962: When Python is compiled with -mcet |
| 216 | # -fcf-protection, function arguments are unusable before |