Skip to content

Commit

Permalink
Data breakpoints
Browse files Browse the repository at this point in the history
Works with CodeLLDB mostly for named things. Expressions don't seem to
be supported by anyone.

Fixed some state issues with the connections being retained across
restarts in watches. ugh. so messy.

Added access type question.

Java debug adapter returns broken breakpoints info response
  • Loading branch information
puremourning committed Sep 27, 2024
1 parent eabcff5 commit bdf734a
Show file tree
Hide file tree
Showing 13 changed files with 294 additions and 26 deletions.
8 changes: 8 additions & 0 deletions autoload/vimspector.vim
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,14 @@ function! vimspector#ShowDisassembly( ... ) abort
py3 _vimspector_session.ShowDisassembly()
endfunction

function! vimspector#AddDataBreakpoint( ... ) abort
if !s:Enabled()
return
endif
" TODO: how to set options?
py3 _vimspector_session.AddDataBreakpoint( {} )
endfunction

function! vimspector#DeleteWatch() abort
if !s:Enabled()
return
Expand Down
68 changes: 60 additions & 8 deletions python3/vimspector/breakpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ def __init__( self,
self._func_breakpoints = []
self._exception_breakpoints = None
self._configured_breakpoints = {}
self._data_breakponts = []

self._server_capabilities = {}

Expand Down Expand Up @@ -523,23 +524,21 @@ def _ClearServerBreakpointData( self, conn: DebugAdapterConnection ):
if not bp[ 'server_bp' ]:
del bp[ 'server_bp' ]


# Clear all instruction breakpoints because they aren't truly portable
# across sessions.
#
# TODO: It might be possible to re-resolve the address stored in the
# breakpoint, though this would only work in a limited way (as load
# addresses will frequently not be the same across runs)


def ShouldKeep( bp ):
def ShouldKeepInsBP( bp ):
if not bp[ 'is_instruction_breakpoint' ]:
return True
if 'address' in bp and bp[ 'session_id' ] != conn.GetSessionId():
return True
return False

breakpoints[ : ] = [ bp for bp in breakpoints if ShouldKeep( bp ) ]
breakpoints[ : ] = [ bp for bp in breakpoints if ShouldKeepInsBP( bp ) ]

# Erase any data breakpoints for this connection too
self._data_breakponts[ : ] = [ bp for bp in self._data_breakponts
if bp[ 'conn' ] != conn.GetSessionId() ]


def _CopyServerLineBreakpointProperties( self,
Expand Down Expand Up @@ -807,7 +806,19 @@ def AddFunctionBreakpoint( self, function, options ):
# 'condition': ...,
# 'hitCondition': ...,
} )
self.UpdateUI()


def AddDataBreakpoint( self,
conn: DebugAdapterConnection,
info,
options ):
self._data_breakponts.append( {
'state': 'ENABLED',
'conn': conn.GetSessionId(),
'info': info,
'options': options
} )
self.UpdateUI()


Expand Down Expand Up @@ -1014,6 +1025,37 @@ def response_handler( conn, msg, bp_idxs = [] ):
failure_handler = response_received
)

if self._data_breakponts and self._server_capabilities[
'supportsDataBreakpoints' ]:
connection: DebugAdapterConnection
for connection in self._connections:
breakpoints = []
for bp in self._data_breakponts:
if bp[ 'state' ] != 'ENABLED':
continue
if bp[ 'conn' ] != connection.GetSessionId():
continue
if not bp[ 'info' ].get( 'dataId' ):
continue

data_bp = {}
data_bp.update( bp[ 'options' ] )
data_bp[ 'dataId' ] = bp[ 'info' ][ 'dataId' ]
breakpoints.append( data_bp )

if breakpoints:
self._awaiting_bp_responses += 1
connection.DoRequest(
lambda msg, conn=connection: response_handler( conn, msg ),
{
'command': 'setDataBreakpoints',
'arguments': {
'breakpoints': breakpoints,
},
},
failure_handler = response_received
)

if self._exception_breakpoints:
for connection in self._connections:
self._awaiting_bp_responses += 1
Expand Down Expand Up @@ -1112,6 +1154,11 @@ def Save( self ):
if bps:
line[ file_name ] = bps

# TODO: Some way to persis data breakpoints? Currently they require
# variablesReference, which is clearly not something that can be persisted
#
# That said, the spec now seems to support data bps on expressions, though i
# can't see any servers which support that.
return {
'line': line,
'function': self._func_breakpoints,
Expand Down Expand Up @@ -1183,6 +1230,11 @@ def _HideBreakpoints( self ):
signs.UnplaceSign( bp[ 'sign_id' ], 'VimspectorBP' )
del bp[ 'sign_id' ]

# TODO could/should we show a sign in the variables view when there's a data
# brakpoint on the variable? Not sure how best to actually do that, but
# maybe the variable view can pass that info when calling AddDataBreakpoint,
# such as the variablesReference/name


def _SignToLine( self, file_name, bp ):
if bp[ 'is_instruction_breakpoint' ]:
Expand Down
31 changes: 30 additions & 1 deletion python3/vimspector/debug_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -1016,7 +1016,36 @@ def OnDisassemblyWindowScrolled( self, win_id ):
self._disassemblyView.OnWindowScrolled( win_id )


@CurrentSession()
@ParentOnly()
def AddDataBreakpoint( self, opts, buf = None, line_num = None ):
# Use the parent session, because the _connection_ comes from the
# variable/watch result that is actually chosen

def add_bp( conn, msg ):
breakpoint_info = msg.get( 'body' )
if not breakpoint_info:
utils.UserMessage( "Can't set data breakpoint here" )
return

if breakpoint_info[ 'dataId' ] is None:
utils.UserMessage(
f"Can't set data breakpoint here: {breakpoint_info[ 'description' ]}"
)
return

access_types = breakpoint_info.get( 'accessTypes' )
if access_types and 'accessType' not in opts:
access_type = utils.SelectFromList( 'What type of access?',
access_types )
if access_type is not None:
opts[ 'accessType' ] = access_type

self._breakpoints.AddDataBreakpoint( conn,
breakpoint_info,
opts )

self._variablesView.GetDataBreakpointInfo( add_bp, buf, line_num )

@IfConnected()
def AddWatch( self, expression ):
self._variablesView.AddWatch( self._connection,
Expand Down
1 change: 1 addition & 0 deletions python3/vimspector/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
'delete': [ '<Del>' ],
'set_value': [ '<C-CR>', '<leader><CR>' ],
'read_memory': [ '<leader>m' ],
'add_data_breakpoint': [ '<F9>' ],
},
'stack_trace': {
'expand_or_jump': [ '<CR>', '<2-LeftMouse>' ],
Expand Down
Loading

0 comments on commit bdf734a

Please sign in to comment.