Support the bash debugger
This required working around some sort of bug where the server returns an invalid content length. Either that or we are somehow processing the same message twice with additional escaping? It's really strange.
This commit is contained in:
parent
f53fb88503
commit
b6a9cba52e
5 changed files with 67 additions and 26 deletions
|
|
@ -21,6 +21,13 @@
|
||||||
"node",
|
"node",
|
||||||
"/Users/ben/.vscode/extensions/ms-python.python-2018.4.0/out/client/debugger/Main.js"
|
"/Users/ben/.vscode/extensions/ms-python.python-2018.4.0/out/client/debugger/Main.js"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"bashdb": {
|
||||||
|
"name": "bashdb",
|
||||||
|
"command": [
|
||||||
|
"node",
|
||||||
|
"/Users/ben/.vscode/extensions/rogalmic.bash-debug-0.2.0/out/bashDebug.js"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
|
|
@ -72,6 +79,24 @@
|
||||||
"program": "/Users/ben/.vim/bundle/vimspector/support/test/cpp/simple_c_program/test",
|
"program": "/Users/ben/.vim/bundle/vimspector/support/test/cpp/simple_c_program/test",
|
||||||
"MIMode": "lldb"
|
"MIMode": "lldb"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"bashdb": {
|
||||||
|
"adapter": "bashdb",
|
||||||
|
"configuration": {
|
||||||
|
"type": "bashdb",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Bash-Debug (simplest configuration)",
|
||||||
|
"program": "/Users/ben/.vim/bundle/YouCompleteMe/install.sh",
|
||||||
|
"args": [],
|
||||||
|
"cwd": "/Users/ben/.vim/bundle/YouCompleteMe",
|
||||||
|
"pathBash": "bash",
|
||||||
|
"pathBashdb": "bashdb",
|
||||||
|
"pathCat": "cat",
|
||||||
|
"pathMkfifo": "mkfifo",
|
||||||
|
"pathPkill": "pkill",
|
||||||
|
"showDebugOutput": true,
|
||||||
|
"trace": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ breakpoint.
|
||||||
* Expand result with `<CR>`.
|
* Expand result with `<CR>`.
|
||||||
* Delete with `<DEL>`.
|
* Delete with `<DEL>`.
|
||||||
|
|
||||||
## Stack Trraces
|
## Stack Traces
|
||||||
|
|
||||||
* In the threads window, use `<CR>` to expand/collapse.
|
* In the threads window, use `<CR>` to expand/collapse.
|
||||||
* Use `<CR>` on a stack frame to jump to it.
|
* Use `<CR>` on a stack frame to jump to it.
|
||||||
|
|
@ -241,12 +241,12 @@ Known not to work:
|
||||||
|
|
||||||
Currently on the author's environment which is macOS.
|
Currently on the author's environment which is macOS.
|
||||||
|
|
||||||
The plugin _might_ work on other unix-like environments but it hasn't been
|
The plugin _might_ work on other UNIX-like environments but it hasn't been
|
||||||
tested. It will almost cerainly not work on Windows.
|
tested. It will almost certainly not work on Windows.
|
||||||
|
|
||||||
Requires:
|
Requires:
|
||||||
|
|
||||||
- Vim 8.1 compiled with python 3 support
|
- Vim 8.1 compiled with python 3 support.
|
||||||
|
|
||||||
# FAQ
|
# FAQ
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,20 +57,21 @@ class CodeView( object ):
|
||||||
self._signs[ 'vimspectorPC' ] = None
|
self._signs[ 'vimspectorPC' ] = None
|
||||||
|
|
||||||
if not frame or not frame[ 'source' ]:
|
if not frame or not frame[ 'source' ]:
|
||||||
return
|
return False
|
||||||
|
|
||||||
vim.current.window = self._window
|
vim.current.window = self._window
|
||||||
|
|
||||||
buffer_number = vim.eval( 'bufnr( "{0}", 1 )'.format(
|
buffer_number = int( vim.eval( 'bufnr( "{0}", 1 )'.format(
|
||||||
frame[ 'source' ][ 'path' ] ) )
|
frame[ 'source' ][ 'path' ] ) ) )
|
||||||
|
|
||||||
try:
|
try:
|
||||||
vim.command( 'bu {0}'.format( buffer_number ) )
|
vim.command( 'bu {0}'.format( buffer_number ) )
|
||||||
|
self._window.cursor = ( frame[ 'line' ], frame[ 'column' ] )
|
||||||
except vim.error as e:
|
except vim.error as e:
|
||||||
if 'E325' not in str( e ):
|
if 'E325' not in str( e ):
|
||||||
raise
|
self._logger.exception(
|
||||||
|
'Unexpected error from vim: {0}'.format( str( e ) ) )
|
||||||
self._window.cursor = ( frame[ 'line' ], frame[ 'column' ] )
|
return False
|
||||||
|
|
||||||
self._signs[ 'vimspectorPC' ] = self._next_sign_id
|
self._signs[ 'vimspectorPC' ] = self._next_sign_id
|
||||||
self._next_sign_id += 1
|
self._next_sign_id += 1
|
||||||
|
|
@ -80,6 +81,7 @@ class CodeView( object ):
|
||||||
frame[ 'line' ],
|
frame[ 'line' ],
|
||||||
frame[ 'source' ][ 'path' ] ) )
|
frame[ 'source' ][ 'path' ] ) )
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
def Clear( self ):
|
def Clear( self ):
|
||||||
if self._signs[ 'vimspectorPC' ]:
|
if self._signs[ 'vimspectorPC' ]:
|
||||||
|
|
|
||||||
|
|
@ -80,24 +80,34 @@ class DebugAdapterConnection( object ):
|
||||||
self._Write( data )
|
self._Write( data )
|
||||||
|
|
||||||
def _ReadHeaders( self ):
|
def _ReadHeaders( self ):
|
||||||
headers = self._buffer.split( bytes( '\r\n\r\n', 'utf-8' ), 1 )
|
parts = self._buffer.split( bytes( '\r\n\r\n', 'utf-8' ), 1 )
|
||||||
|
|
||||||
if len( headers ) > 1:
|
if len( parts ) > 1:
|
||||||
for header_line in headers[ 0 ].split( bytes( '\r\n', 'utf-8' ) ):
|
headers = parts[ 0 ]
|
||||||
|
for header_line in headers.split( bytes( '\r\n', 'utf-8' ) ):
|
||||||
if header_line.strip():
|
if header_line.strip():
|
||||||
key, value = str( header_line, 'utf-8' ).split( ':', 1 )
|
key, value = str( header_line, 'utf-8' ).split( ':', 1 )
|
||||||
self._headers[ key ] = value
|
self._headers[ key ] = value
|
||||||
|
|
||||||
# Chomp (+4 for the 2 newlines which were the separator)
|
# Chomp (+4 for the 2 newlines which were the separator)
|
||||||
# self._buffer = self._buffer[ len( headers[ 0 ] ) + 4 : ]
|
# self._buffer = self._buffer[ len( headers[ 0 ] ) + 4 : ]
|
||||||
self._buffer = headers[ 1 ]
|
self._buffer = parts[ 1 ]
|
||||||
self._SetState( 'READ_BODY' )
|
self._SetState( 'READ_BODY' )
|
||||||
return
|
return
|
||||||
|
|
||||||
# otherwise waiting for more data
|
# otherwise waiting for more data
|
||||||
|
|
||||||
def _ReadBody( self ):
|
def _ReadBody( self ):
|
||||||
content_length = int( self._headers[ 'Content-Length' ] )
|
try:
|
||||||
|
content_length = int( self._headers[ 'Content-Length' ] )
|
||||||
|
except KeyError:
|
||||||
|
# Ug oh. We seem to have all the headers, but no Content-Length
|
||||||
|
# Skip to reading headers. Because, what else can we do.
|
||||||
|
self._logger.error( 'Missing Content-Length header in: {0}'.format(
|
||||||
|
json.dumps( self._headers ) ) )
|
||||||
|
self._buffer = bytes( '', 'utf-8' )
|
||||||
|
self._SetState( 'READ_HEADER' )
|
||||||
|
return
|
||||||
|
|
||||||
if len( self._buffer ) < content_length:
|
if len( self._buffer ) < content_length:
|
||||||
# Need more data
|
# Need more data
|
||||||
|
|
|
||||||
|
|
@ -293,7 +293,7 @@ class DebugSession( object ):
|
||||||
self.SetCurrentFrame( None )
|
self.SetCurrentFrame( None )
|
||||||
|
|
||||||
def SetCurrentFrame( self, frame ):
|
def SetCurrentFrame( self, frame ):
|
||||||
self._codeView.SetCurrentFrame( frame )
|
ret = self._codeView.SetCurrentFrame( frame )
|
||||||
|
|
||||||
if frame:
|
if frame:
|
||||||
self._variablesView.LoadScopes( frame )
|
self._variablesView.LoadScopes( frame )
|
||||||
|
|
@ -302,6 +302,8 @@ class DebugSession( object ):
|
||||||
self._stackTraceView.Clear()
|
self._stackTraceView.Clear()
|
||||||
self._variablesView.Clear()
|
self._variablesView.Clear()
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
def _StartDebugAdapter( self ):
|
def _StartDebugAdapter( self ):
|
||||||
self._logger.info( 'Starting debug adapter with: {0}'.format( json.dumps(
|
self._logger.info( 'Starting debug adapter with: {0}'.format( json.dumps(
|
||||||
self._adapter ) ) )
|
self._adapter ) ) )
|
||||||
|
|
@ -383,9 +385,15 @@ class DebugSession( object ):
|
||||||
'command': 'initialize',
|
'command': 'initialize',
|
||||||
'arguments': {
|
'arguments': {
|
||||||
'adapterID': adapter_config.get( 'name', 'adapter' ),
|
'adapterID': adapter_config.get( 'name', 'adapter' ),
|
||||||
|
'clientID': 'vimspector',
|
||||||
|
'clientName': 'vimspector',
|
||||||
'linesStartAt1': True,
|
'linesStartAt1': True,
|
||||||
'columnsStartAt1': True,
|
'columnsStartAt1': True,
|
||||||
|
'locale': 'en_GB',
|
||||||
'pathFormat': 'path',
|
'pathFormat': 'path',
|
||||||
|
'supportsVariableType': True,
|
||||||
|
'supportsVariablePaging': False,
|
||||||
|
'supportsRunInTerminalRequest': True
|
||||||
},
|
},
|
||||||
} )
|
} )
|
||||||
|
|
||||||
|
|
@ -407,18 +415,14 @@ class DebugSession( object ):
|
||||||
|
|
||||||
def OnEvent_initialized( self, message ):
|
def OnEvent_initialized( self, message ):
|
||||||
self._SendBreakpoints()
|
self._SendBreakpoints()
|
||||||
self._connection.DoRequest( None, {
|
self._connection.DoRequest(
|
||||||
'command': 'configurationDone',
|
lambda msg: self._stackTraceView.LoadThreads( True ),
|
||||||
} )
|
{
|
||||||
|
'command': 'configurationDone',
|
||||||
self._stackTraceView.LoadThreads( True )
|
}
|
||||||
|
)
|
||||||
|
|
||||||
def OnEvent_thread( self, message ):
|
def OnEvent_thread( self, message ):
|
||||||
if message[ 'body' ][ 'reason' ] == 'started':
|
|
||||||
pass
|
|
||||||
elif message[ 'body' ][ 'reason' ] == 'exited':
|
|
||||||
pass
|
|
||||||
|
|
||||||
self._stackTraceView.OnThreadEvent( message[ 'body' ] )
|
self._stackTraceView.OnThreadEvent( message[ 'body' ] )
|
||||||
|
|
||||||
def OnEvent_breakpoint( self, message ):
|
def OnEvent_breakpoint( self, message ):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue