Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
ef747e9a
Commit
ef747e9a
authored
Nov 01, 2010
by
Mark Florisson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reentrant gdb.execute()
cy locals, cy globals
parent
d07e7567
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
162 additions
and
103 deletions
+162
-103
Cython/Compiler/ParseTreeTransforms.py
Cython/Compiler/ParseTreeTransforms.py
+7
-3
Cython/Debugger/Tests/codefile
Cython/Debugger/Tests/codefile
+2
-2
Cython/Debugger/Tests/test_libcython_in_gdb.py
Cython/Debugger/Tests/test_libcython_in_gdb.py
+41
-17
Cython/Debugger/libcython.py
Cython/Debugger/libcython.py
+50
-50
Cython/Debugger/libpython.py
Cython/Debugger/libpython.py
+62
-31
No files found.
Cython/Compiler/ParseTreeTransforms.py
View file @
ef747e9a
...
@@ -7,6 +7,7 @@ from Cython.Compiler.UtilNodes import *
...
@@ -7,6 +7,7 @@ from Cython.Compiler.UtilNodes import *
from
Cython.Compiler.TreeFragment
import
TreeFragment
,
TemplateTransform
from
Cython.Compiler.TreeFragment
import
TreeFragment
,
TemplateTransform
from
Cython.Compiler.StringEncoding
import
EncodedString
from
Cython.Compiler.StringEncoding
import
EncodedString
from
Cython.Compiler.Errors
import
error
,
CompileError
from
Cython.Compiler.Errors
import
error
,
CompileError
from
Cython.Compiler
import
PyrexTypes
try
:
try
:
set
set
...
@@ -1469,11 +1470,14 @@ class DebugTransform(CythonTransform):
...
@@ -1469,11 +1470,14 @@ class DebugTransform(CythonTransform):
# 2.3 compatibility. Serialize global variables
# 2.3 compatibility. Serialize global variables
self
.
tb
.
start
(
'Globals'
)
self
.
tb
.
start
(
'Globals'
)
entries
=
{}
entries
=
{}
for
k
,
v
in
node
.
scope
.
entries
.
iteritems
():
for
k
,
v
in
node
.
scope
.
entries
.
iteritems
():
if
(
v
.
qualified_name
not
in
self
.
visited
and
if
(
v
.
qualified_name
not
in
self
.
visited
and
not
not
v
.
name
.
startswith
(
'__pyx_'
)):
v
.
name
.
startswith
(
'__pyx_'
)
and
not
v
.
type
.
is_cfunction
and
not
v
.
type
.
is_extension_type
):
entries
[
k
]
=
v
entries
[
k
]
=
v
self
.
serialize_local_variables
(
entries
)
self
.
serialize_local_variables
(
entries
)
self
.
tb
.
end
(
'Globals'
)
self
.
tb
.
end
(
'Globals'
)
# self.tb.end('Module') # end Module after the line number mapping in
# self.tb.end('Module') # end Module after the line number mapping in
...
...
Cython/Debugger/Tests/codefile
View file @
ef747e9a
...
@@ -6,8 +6,8 @@ cdef extern:
...
@@ -6,8 +6,8 @@ cdef extern:
import os
import os
cdef int c_var =
0
cdef int c_var =
12
python_var =
0
python_var =
13
def spam(a=0):
def spam(a=0):
cdef:
cdef:
...
...
Cython/Debugger/Tests/test_libcython_in_gdb.py
View file @
ef747e9a
...
@@ -8,6 +8,7 @@ Cython.Debugger.Cygdb.make_command_file()
...
@@ -8,6 +8,7 @@ Cython.Debugger.Cygdb.make_command_file()
import
os
import
os
import
sys
import
sys
import
trace
import
trace
import
inspect
import
warnings
import
warnings
import
unittest
import
unittest
import
traceback
import
traceback
...
@@ -19,11 +20,16 @@ from Cython.Debugger import libcython
...
@@ -19,11 +20,16 @@ from Cython.Debugger import libcython
from
Cython.Debugger
import
libpython
from
Cython.Debugger
import
libpython
from
Cython.Debugger.Tests
import
TestLibCython
as
test_libcython
from
Cython.Debugger.Tests
import
TestLibCython
as
test_libcython
# for some reason sys.argv is missing in gdb
# for some reason sys.argv is missing in gdb
sys
.
argv
=
[
'gdb'
]
sys
.
argv
=
[
'gdb'
]
class
DebugTestCase
(
unittest
.
TestCase
):
class
DebugTestCase
(
unittest
.
TestCase
):
"""
Base class for test cases. On teardown it kills the inferior and unsets
all breakpoints.
"""
def
__init__
(
self
,
name
):
def
__init__
(
self
,
name
):
super
(
DebugTestCase
,
self
).
__init__
(
name
)
super
(
DebugTestCase
,
self
).
__init__
(
name
)
...
@@ -50,25 +56,26 @@ class DebugTestCase(unittest.TestCase):
...
@@ -50,25 +56,26 @@ class DebugTestCase(unittest.TestCase):
lineno
=
test_libcython
.
source_to_lineno
[
source_line
]
lineno
=
test_libcython
.
source_to_lineno
[
source_line
]
frame
=
gdb
.
selected_frame
()
frame
=
gdb
.
selected_frame
()
self
.
assertEqual
(
libcython
.
cy
.
step
.
lineno
(
frame
),
lineno
)
self
.
assertEqual
(
libcython
.
cy
.
step
.
lineno
(
frame
),
lineno
)
def
break_and_run
(
self
,
source_line
):
break_lineno
=
test_libcython
.
source_to_lineno
[
source_line
]
gdb
.
execute
(
'cy break codefile:%d'
%
break_lineno
,
to_string
=
True
)
gdb
.
execute
(
'run'
,
to_string
=
True
)
def
tearDown
(
self
):
def
tearDown
(
self
):
gdb
.
execute
(
'delete breakpoints'
,
to_string
=
True
)
gdb
.
execute
(
'delete breakpoints'
,
to_string
=
True
)
try
:
try
:
gdb
.
execute
(
'kill inferior 1'
,
to_string
=
True
)
gdb
.
execute
(
'kill inferior 1'
,
to_string
=
True
)
except
RuntimeError
:
except
RuntimeError
:
pass
pass
def
break_and_run
(
self
,
source_line
):
break_lineno
=
test_libcython
.
source_to_lineno
[
source_line
]
gdb
.
execute
(
'cy break codefile:%d'
%
break_lineno
,
to_string
=
True
)
gdb
.
execute
(
'run'
,
to_string
=
True
)
class
TestDebugInformationClasses
(
DebugTestCase
):
class
TestDebugInformationClasses
(
DebugTestCase
):
def
test_CythonModule
(
self
):
def
test_CythonModule
(
self
):
"test that debug information was parsed properly into data structures"
"test that debug information was parsed properly into data structures"
self
.
assertEqual
(
self
.
module
.
name
,
'codefile'
)
self
.
assertEqual
(
self
.
module
.
name
,
'codefile'
)
global_vars
=
(
'c_var'
,
'python_var'
,
'
SomeClass'
,
'
__name__'
,
global_vars
=
(
'c_var'
,
'python_var'
,
'__name__'
,
'__builtins__'
,
'__doc__'
,
'__file__'
)
'__builtins__'
,
'__doc__'
,
'__file__'
)
assert
set
(
global_vars
).
issubset
(
self
.
module
.
globals
)
assert
set
(
global_vars
).
issubset
(
self
.
module
.
globals
)
...
@@ -115,7 +122,6 @@ class TestBreak(DebugTestCase):
...
@@ -115,7 +122,6 @@ class TestBreak(DebugTestCase):
def
test_break
(
self
):
def
test_break
(
self
):
result
=
libpython
.
_execute
(
'cy break codefile.spam'
,
to_string
=
True
)
result
=
libpython
.
_execute
(
'cy break codefile.spam'
,
to_string
=
True
)
print
>>
sys
.
stderr
,
repr
(
result
)
assert
self
.
spam_func
.
cname
in
result
assert
self
.
spam_func
.
cname
in
result
self
.
assertEqual
(
len
(
gdb
.
breakpoints
()),
1
)
self
.
assertEqual
(
len
(
gdb
.
breakpoints
()),
1
)
...
@@ -140,6 +146,7 @@ class TestStep(DebugStepperTestCase):
...
@@ -140,6 +146,7 @@ class TestStep(DebugStepperTestCase):
Test stepping. Stepping happens in the code found in
Test stepping. Stepping happens in the code found in
Cython/Debugger/Tests/codefile.
Cython/Debugger/Tests/codefile.
"""
"""
def
test_cython_step
(
self
):
def
test_cython_step
(
self
):
gdb
.
execute
(
'cy break codefile.spam'
)
gdb
.
execute
(
'cy break codefile.spam'
)
libcython
.
parameters
.
step_into_c_code
.
value
=
False
libcython
.
parameters
.
step_into_c_code
.
value
=
False
...
@@ -197,8 +204,28 @@ class TestNext(DebugStepperTestCase):
...
@@ -197,8 +204,28 @@ class TestNext(DebugStepperTestCase):
self
.
lineno_equals
(
line
)
self
.
lineno_equals
(
line
)
class
TestLocalsGlobals
(
DebugTestCase
):
def
test_locals
(
self
):
self
.
break_and_run
(
'int(10)'
)
result
=
gdb
.
execute
(
'cy locals'
,
to_string
=
True
)
assert
'a = 0'
in
result
,
repr
(
result
)
assert
'b = 1'
in
result
,
repr
(
result
)
assert
'c = 2'
in
result
,
repr
(
result
)
def
test_globals
(
self
):
self
.
break_and_run
(
'int(10)'
)
result
=
gdb
.
execute
(
'cy globals'
,
to_string
=
True
)
assert
'__name__ ='
in
result
,
repr
(
result
)
assert
'__doc__ ='
in
result
,
repr
(
result
)
assert
'os ='
in
result
,
repr
(
result
)
assert
'c_var = 12'
in
result
,
repr
(
result
)
assert
'python_var = 13'
in
result
,
repr
(
result
)
def
_main
():
def
_main
():
# unittest.main(module=__import__(__name__, fromlist=['']))
try
:
try
:
gdb
.
lookup_type
(
'PyModuleObject'
)
gdb
.
lookup_type
(
'PyModuleObject'
)
except
RuntimeError
:
except
RuntimeError
:
...
@@ -207,17 +234,14 @@ def _main():
...
@@ -207,17 +234,14 @@ def _main():
"-g or get a debug build (configure with --with-pydebug)."
)
"-g or get a debug build (configure with --with-pydebug)."
)
warnings
.
warn
(
msg
)
warnings
.
warn
(
msg
)
else
:
else
:
tests
=
(
m
=
__import__
(
__name__
,
fromlist
=
[
''
])
TestDebugInformationClasses
,
tests
=
inspect
.
getmembers
(
m
,
inspect
.
isclass
)
TestParameters
,
TestBreak
,
TestStep
,
TestNext
,
)
# test_support.run_unittest(tests)
# test_support.run_unittest(tests)
test_loader
=
unittest
.
TestLoader
()
test_loader
=
unittest
.
TestLoader
()
suite
=
unittest
.
TestSuite
(
suite
=
unittest
.
TestSuite
(
[
test_loader
.
loadTestsFromTestCase
(
cls
)
for
cls
in
tests
])
[
test_loader
.
loadTestsFromTestCase
(
cls
)
for
name
,
cls
in
tests
])
result
=
unittest
.
TextTestRunner
(
verbosity
=
1
).
run
(
suite
)
result
=
unittest
.
TextTestRunner
(
verbosity
=
1
).
run
(
suite
)
if
not
result
.
wasSuccessful
():
if
not
result
.
wasSuccessful
():
...
...
Cython/Debugger/libcython.py
View file @
ef747e9a
...
@@ -229,6 +229,7 @@ class CythonBase(object):
...
@@ -229,6 +229,7 @@ class CythonBase(object):
source_desc
,
lineno
=
self
.
get_source_desc
()
source_desc
,
lineno
=
self
.
get_source_desc
()
return
source_desc
.
get_source
(
lineno
)
return
source_desc
.
get_source
(
lineno
)
@
default_selected_gdb_frame
()
def
is_relevant_function
(
self
,
frame
):
def
is_relevant_function
(
self
,
frame
):
"""
"""
returns whether we care about a frame on the user-level when debugging
returns whether we care about a frame on the user-level when debugging
...
@@ -236,7 +237,7 @@ class CythonBase(object):
...
@@ -236,7 +237,7 @@ class CythonBase(object):
"""
"""
name
=
frame
.
name
()
name
=
frame
.
name
()
older_frame
=
frame
.
older
()
older_frame
=
frame
.
older
()
# print 'is_relevant_function', name
if
self
.
is_cython_function
(
frame
)
or
self
.
is_python_function
(
frame
):
if
self
.
is_cython_function
(
frame
)
or
self
.
is_python_function
(
frame
):
return
True
return
True
elif
(
parameters
.
step_into_c_code
and
elif
(
parameters
.
step_into_c_code
and
...
@@ -246,7 +247,13 @@ class CythonBase(object):
...
@@ -246,7 +247,13 @@ class CythonBase(object):
return
name
in
cython_func
.
step_into_functions
return
name
in
cython_func
.
step_into_functions
return
False
return
False
def
print_cython_var_if_initialized
(
self
,
varname
):
try
:
self
.
cy
.
print_
.
invoke
(
varname
,
True
)
except
gdb
.
GdbError
:
# variable not initialized yet
pass
class
SourceFileDescriptor
(
object
):
class
SourceFileDescriptor
(
object
):
def
__init__
(
self
,
filename
,
lexer
,
formatter
=
None
):
def
__init__
(
self
,
filename
,
lexer
,
formatter
=
None
):
...
@@ -456,7 +463,9 @@ class CyCy(CythonCommand):
...
@@ -456,7 +463,9 @@ class CyCy(CythonCommand):
for
command_name
,
command
in
commands
.
iteritems
():
for
command_name
,
command
in
commands
.
iteritems
():
command
.
cy
=
self
command
.
cy
=
self
setattr
(
self
,
command_name
,
command
)
setattr
(
self
,
command_name
,
command
)
self
.
cy
=
self
# Cython module namespace
# Cython module namespace
self
.
cython_namespace
=
{}
self
.
cython_namespace
=
{}
...
@@ -507,6 +516,7 @@ class CyImport(CythonCommand):
...
@@ -507,6 +516,7 @@ class CyImport(CythonCommand):
# update the global function mappings
# update the global function mappings
name
=
cython_function
.
name
name
=
cython_function
.
name
qname
=
cython_function
.
qualified_name
self
.
cy
.
functions_by_name
[
name
].
append
(
cython_function
)
self
.
cy
.
functions_by_name
[
name
].
append
(
cython_function
)
self
.
cy
.
functions_by_qualified_name
[
self
.
cy
.
functions_by_qualified_name
[
...
@@ -514,9 +524,7 @@ class CyImport(CythonCommand):
...
@@ -514,9 +524,7 @@ class CyImport(CythonCommand):
self
.
cy
.
functions_by_cname
[
self
.
cy
.
functions_by_cname
[
cython_function
.
cname
]
=
cython_function
cython_function
.
cname
]
=
cython_function
d
=
cython_module
.
functions
d
=
cython_module
.
functions
[
qname
]
=
cython_function
L
=
d
.
setdefault
(
cython_function
.
qualified_name
,
[])
L
.
append
(
cython_function
)
for
local
in
function
.
find
(
'Locals'
):
for
local
in
function
.
find
(
'Locals'
):
d
=
local
.
attrib
d
=
local
.
attrib
...
@@ -658,17 +666,17 @@ class CythonCodeStepper(CythonCommand, libpython.GenericCodeStepper):
...
@@ -658,17 +666,17 @@ class CythonCodeStepper(CythonCommand, libpython.GenericCodeStepper):
def
get_source_line
(
self
,
frame
):
def
get_source_line
(
self
,
frame
):
# We may have ended up in a Python, Cython, or C function
# We may have ended up in a Python, Cython, or C function
# In case of C, don't display any additional data (gdb already
result
=
None
# does this)
result
=
''
if
self
.
is_cython_function
(
frame
)
or
self
.
is_python_function
(
frame
):
if
self
.
is_cython_function
(
frame
)
or
self
.
is_python_function
(
frame
):
try
:
try
:
result
=
super
(
CythonCodeStepper
,
self
).
get_source_line
(
frame
)
line
=
super
(
CythonCodeStepper
,
self
).
get_source_line
(
frame
)
except
gdb
.
GdbError
:
except
gdb
.
GdbError
:
result
=
''
pass
else
:
return
result
.
lstrip
()
result
=
line
.
lstrip
()
return
result
@
classmethod
@
classmethod
def
register
(
cls
):
def
register
(
cls
):
...
@@ -724,8 +732,12 @@ class CyPrint(CythonCommand):
...
@@ -724,8 +732,12 @@ class CyPrint(CythonCommand):
@
dispatch_on_frame
(
c_command
=
'print'
,
python_command
=
'py-print'
)
@
dispatch_on_frame
(
c_command
=
'print'
,
python_command
=
'py-print'
)
def
invoke
(
self
,
name
,
from_tty
):
def
invoke
(
self
,
name
,
from_tty
):
gdb
.
execute
(
'print '
+
self
.
cy
.
cy_cname
.
invoke
(
name
,
string
=
True
))
cname
=
self
.
cy
.
cy_cname
.
invoke
(
name
,
string
=
True
)
try
:
print
'%s = %s'
%
(
name
,
gdb
.
parse_and_eval
(
cname
))
except
RuntimeError
,
e
:
raise
gdb
.
GdbError
(
"Variable %s is not initialized yet."
%
(
name
,))
def
complete
(
self
):
def
complete
(
self
):
if
self
.
is_cython_function
():
if
self
.
is_cython_function
():
f
=
self
.
get_cython_function
()
f
=
self
.
get_cython_function
()
...
@@ -743,32 +755,11 @@ class CyLocals(CythonCommand):
...
@@ -743,32 +755,11 @@ class CyLocals(CythonCommand):
command_class
=
gdb
.
COMMAND_STACK
command_class
=
gdb
.
COMMAND_STACK
completer_class
=
gdb
.
COMPLETE_NONE
completer_class
=
gdb
.
COMPLETE_NONE
def
ns
(
self
):
return
self
.
get_cython_function
().
locals
@
dispatch_on_frame
(
c_command
=
'info locals'
,
python_command
=
'py-locals'
)
@
dispatch_on_frame
(
c_command
=
'info locals'
,
python_command
=
'py-locals'
)
def
invoke
(
self
,
name
,
from_tty
):
def
invoke
(
self
,
args
,
from_tty
):
try
:
for
varname
in
self
.
get_cython_function
().
locals
:
ns
=
self
.
ns
()
self
.
print_cython_var_if_initialized
(
varname
)
except
RuntimeError
,
e
:
print
e
.
args
[
0
]
return
if
ns
is
None
:
raise
gdb
.
GdbError
(
'Information of Cython locals could not be obtained. '
'Is this an actual Cython function and did you '
"'cy import' the debug information?"
)
for
var
in
ns
.
itervalues
():
val
=
gdb
.
parse_and_eval
(
var
.
cname
)
if
var
.
type
==
PythonObject
:
result
=
libpython
.
PyObjectPtr
.
from_pyobject_ptr
(
val
)
else
:
result
=
val
print
'%s = %s'
%
(
var
.
name
,
result
)
class
CyGlobals
(
CythonCommand
):
class
CyGlobals
(
CythonCommand
):
"""
"""
...
@@ -779,12 +770,8 @@ class CyGlobals(CythonCommand):
...
@@ -779,12 +770,8 @@ class CyGlobals(CythonCommand):
command_class
=
gdb
.
COMMAND_STACK
command_class
=
gdb
.
COMMAND_STACK
completer_class
=
gdb
.
COMPLETE_NONE
completer_class
=
gdb
.
COMPLETE_NONE
def
ns
(
self
):
return
self
.
get_cython_function
().
globals
@
dispatch_on_frame
(
c_command
=
'info variables'
,
python_command
=
'py-globals'
)
@
dispatch_on_frame
(
c_command
=
'info variables'
,
python_command
=
'py-globals'
)
def
invoke
(
self
,
name
,
from_tty
):
def
invoke
(
self
,
args
,
from_tty
):
# include globals from the debug info XML file!
m
=
gdb
.
parse_and_eval
(
'__pyx_m'
)
m
=
gdb
.
parse_and_eval
(
'__pyx_m'
)
try
:
try
:
...
@@ -792,16 +779,29 @@ class CyGlobals(CythonCommand):
...
@@ -792,16 +779,29 @@ class CyGlobals(CythonCommand):
except
RuntimeError
:
except
RuntimeError
:
raise
gdb
.
GdbError
(
textwrap
.
dedent
(
"""
raise
gdb
.
GdbError
(
textwrap
.
dedent
(
"""
Unable to lookup type PyModuleObject, did you compile python
Unable to lookup type PyModuleObject, did you compile python
with debugging support (-g)? If this installation is from your
with debugging support (-g)?
package manager, install python-dbg and run the debug version
of python or compile it yourself.
"""
))
"""
))
m
=
m
.
cast
(
PyModuleObject
.
pointer
())
m
=
m
.
cast
(
PyModuleObject
.
pointer
())
d
=
libpython
.
PyObjectPtr
.
from_pyobject_ptr
(
m
[
'md_dict'
])
d
=
libpython
.
PyObjectPtr
.
from_pyobject_ptr
(
m
[
'md_dict'
])
print
d
.
get_truncated_repr
(
1000
)
seen
=
set
()
for
k
,
v
in
d
.
iteritems
():
# Note: k and v are values in the inferior, they are
# libpython.PyObjectPtr objects
k
=
k
.
get_truncated_repr
(
libpython
.
MAX_OUTPUT_LEN
)
# make it look like an actual name (inversion of repr())
k
=
k
[
1
:
-
1
].
decode
(
'string-escape'
)
v
=
v
.
get_truncated_repr
(
libpython
.
MAX_OUTPUT_LEN
)
seen
.
add
(
k
)
print
'%s = %s'
%
(
k
,
v
)
module_globals
=
self
.
get_cython_function
().
module
.
globals
for
varname
in
seen
.
symmetric_difference
(
module_globals
):
self
.
print_cython_var_if_initialized
(
varname
)
# Functions
# Functions
class
CyCName
(
gdb
.
Function
,
CythonBase
):
class
CyCName
(
gdb
.
Function
,
CythonBase
):
...
...
Cython/Debugger/libpython.py
View file @
ef747e9a
...
@@ -47,6 +47,7 @@ from __future__ import with_statement
...
@@ -47,6 +47,7 @@ from __future__ import with_statement
import
os
import
os
import
sys
import
sys
import
atexit
import
tempfile
import
tempfile
import
gdb
import
gdb
...
@@ -1454,34 +1455,62 @@ class PyLocals(gdb.Command):
...
@@ -1454,34 +1455,62 @@ class PyLocals(gdb.Command):
PyLocals()
PyLocals()
def execute(command, from_tty=False, to_string=False
):
class _LoggingState(object
):
"""
"""
Replace gdb.execute() with this function and have it accept a '
to_string
'
State that helps to provide a reentrant gdb.execute() function.
argument (new in 7.2). Have it properly capture stderr also.
Unfortuntaly, this function is not reentrant.
"""
"""
if not to_string:
return _execute(command, from_tty)
fd, filename = tempfile.mkstemp()
try
:
def __init__(self)
:
_execute("set logging file %s" % filename
)
self.fd, self.filename = tempfile.mkstemp(
)
_execute("set logging redirect on"
)
self.file = os.fdopen(self.fd, '
r
+
'
)
_execute("set logging
on"
)
_execute("set logging
file %s" % self.filename
)
_execute("set pagination off")
self.file_position_stack = []
_execute(command, from_tty)
atexit.register(os.close, self.fd)
finally:
atexit.register(os.remove, self.filename)
data = os.fdopen(fd).read()
os.remove(filename)
def __enter__(self):
_execute("set logging off")
if not self.file_position_stack:
_execute("set pagination on")
_execute("set logging redirect on")
return data
_execute("set logging on")
_execute("set pagination off")
self.file_position_stack.append(os.fstat(self.fd).st_size)
return self
def getoutput(self):
gdb.flush()
self.file.seek(self.file_position_stack[-1])
result = self.file.read()
return result
def __exit__(self, exc_type, exc_val, tb):
startpos = self.file_position_stack.pop()
self.file.seek(startpos)
self.file.truncate()
if not self.file_position_stack:
_execute("set logging off")
_execute("set logging redirect off")
_execute("set pagination on")
def execute(command, from_tty=True, to_string=False):
"""
Replace gdb.execute() with this function and have it accept a '
to_string
'
argument (new in 7.2). Have it properly capture stderr also. Ensure
reentrancy.
"""
if to_string:
with _logging_state as state:
_execute(command, from_tty)
return state.getoutput()
else:
_execute(command, from_tty)
_execute = gdb.execute
_execute = gdb.execute
gdb.execute = execute
gdb.execute = execute
_logging_state = _LoggingState()
class GenericCodeStepper(gdb.Command):
class GenericCodeStepper(gdb.Command):
...
@@ -1494,7 +1523,9 @@ class GenericCodeStepper(gdb.Command):
...
@@ -1494,7 +1523,9 @@ class GenericCodeStepper(gdb.Command):
is_relevant_function(frame) - tells whether we care about frame '
frame
'
is_relevant_function(frame) - tells whether we care about frame '
frame
'
get_source_line(frame) - get the line of source code for the
get_source_line(frame) - get the line of source code for the
current line (only called for a relevant
current line (only called for a relevant
frame)
frame). If the source code cannot be
retrieved this function should
return None
This class provides an '
invoke
' method that invokes a '
step
' or '
step
-
over
'
This class provides an '
invoke
' method that invokes a '
step
' or '
step
-
over
'
depending on the '
stepper
' argument.
depending on the '
stepper
' argument.
...
@@ -1545,12 +1576,16 @@ class GenericCodeStepper(gdb.Command):
...
@@ -1545,12 +1576,16 @@ class GenericCodeStepper(gdb.Command):
return not (hit_breakpoint or new_lineno or is_relevant_function)
return not (hit_breakpoint or new_lineno or is_relevant_function)
def _end_stepping(self):
def _end_stepping(self):
# sys.stdout.write(self.result)
if self.stopped_running:
sys.stdout.write(self.result)
if not self.stopped_running
:
else
:
frame = gdb.selected_frame()
frame = gdb.selected_frame()
if self.is_relevant_function(frame):
if self.is_relevant_function(frame):
print self.get_source_line(frame)
output = self.get_source_line(frame)
if output is None:
sys.stdout.write(self.result)
else:
print output
def _stackdepth(self, frame):
def _stackdepth(self, frame):
depth = 0
depth = 0
...
@@ -1600,8 +1635,7 @@ class PythonCodeStepper(GenericCodeStepper):
...
@@ -1600,8 +1635,7 @@ class PythonCodeStepper(GenericCodeStepper):
try:
try:
return self.pyframe(frame).current_line().rstrip()
return self.pyframe(frame).current_line().rstrip()
except IOError, e:
except IOError, e:
gdb.GdbError('
Unable
to
retrieve
source
code
:
%
s
' % (e,))
return None
class PyStep(PythonCodeStepper):
class PyStep(PythonCodeStepper):
"Step through Python code."
"Step through Python code."
...
@@ -1611,6 +1645,3 @@ class PyNext(PythonCodeStepper):
...
@@ -1611,6 +1645,3 @@ class PyNext(PythonCodeStepper):
py_step = PyStep('
py
-
step
', stepper=True)
py_step = PyStep('
py
-
step
', stepper=True)
py_next = PyNext('
py
-
next
', stepper=False)
py_next = PyNext('
py
-
next
', stepper=False)
class PyShowCCode(gdb.Parameter):
pass
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment