1
- import * as mi from 'cdt-gdb-adapter/dist/mi' ;
2
1
import { DebugProtocol } from 'vscode-debugprotocol' ;
3
- import { GDBDebugSession , LaunchRequestArguments } from 'cdt-gdb-adapter/dist/GDBDebugSession' ;
2
+ import { GDBDebugSession , FrameVariableReference } from 'cdt-gdb-adapter/dist/GDBDebugSession' ;
4
3
import { GDBBackend } from 'cdt-gdb-adapter/dist/GDBBackend' ;
4
+ import * as mi from 'cdt-gdb-adapter/dist/mi' ;
5
5
import { ArduinoGDBBackend } from './arduino-gdb-backend' ;
6
+ import { ArduinoVariableHandler } from './arduino-variable-handler' ;
7
+ import { Scope } from 'vscode-debugadapter' ;
6
8
7
9
export interface ArduinoLaunchRequestArguments extends DebugProtocol . LaunchRequestArguments {
8
10
arduinoCli ?: string ;
@@ -11,26 +13,32 @@ export interface ArduinoLaunchRequestArguments extends DebugProtocol.LaunchReque
11
13
uploadPort ?: string ;
12
14
}
13
15
16
+ const GLOBAL_HANDLE_ID = 0xFE ;
17
+ const STATIC_HANDLES_START = 0x010000 ;
18
+ const STATIC_HANDLES_FINISH = 0x01FFFF ;
19
+
14
20
export class ArduinoDebugSession extends GDBDebugSession {
15
21
16
- protected get arduinoBackend ( ) : ArduinoGDBBackend {
22
+ private _variableHandler : ArduinoVariableHandler ;
23
+
24
+ get arduinoBackend ( ) : ArduinoGDBBackend {
17
25
return this . gdb as ArduinoGDBBackend ;
18
26
}
19
27
20
- protected createBackend ( ) : GDBBackend {
21
- return new ArduinoGDBBackend ( ) ;
28
+ protected get variableHandler ( ) {
29
+ if ( this . _variableHandler ) {
30
+ return this . _variableHandler ;
31
+ }
32
+ if ( ! this . gdb ) {
33
+ throw new Error ( "GDB backend is not ready." ) ;
34
+ }
35
+ const handler = new ArduinoVariableHandler ( this , this . frameHandles , this . variableHandles ) ;
36
+ this . _variableHandler = handler ;
37
+ return handler ;
22
38
}
23
39
24
- protected launchRequest ( response : DebugProtocol . LaunchResponse , args : LaunchRequestArguments ) : Promise < void > {
25
- const additionalCommands = [
26
- '-interpreter-exec console "monitor reset halt"'
27
- ] ;
28
- if ( ! args . initCommands ) {
29
- args . initCommands = additionalCommands ;
30
- } else {
31
- args . initCommands . push ( ...additionalCommands ) ;
32
- }
33
- return super . launchRequest ( response , args ) ;
40
+ protected createBackend ( ) : GDBBackend {
41
+ return new ArduinoGDBBackend ( ) ;
34
42
}
35
43
36
44
protected async configurationDoneRequest ( response : DebugProtocol . ConfigurationDoneResponse ) : Promise < void > {
@@ -50,16 +58,75 @@ export class ArduinoDebugSession extends GDBDebugSession {
50
58
this . gdb . pause ( ) ;
51
59
await waitPromise ;
52
60
}
53
- try {
54
- await this . arduinoBackend . sendTargetDetach ( ) ;
55
- } catch ( e ) {
56
- // Need to catch here as the command result being returned will never exist as it's detached
57
- }
58
61
await this . gdb . sendGDBExit ( ) ;
59
62
this . sendResponse ( response ) ;
60
63
} catch ( err ) {
61
64
this . sendErrorResponse ( response , 1 , err . message ) ;
62
65
}
63
66
}
64
67
68
+ protected async stackTraceRequest ( response : DebugProtocol . StackTraceResponse , args : DebugProtocol . StackTraceArguments ) : Promise < void > {
69
+ try {
70
+
71
+ return super . stackTraceRequest ( response , args ) ;
72
+ } catch ( err ) {
73
+ this . sendErrorResponse ( response , 1 , err . message ) ;
74
+ }
75
+ }
76
+
77
+ protected scopesRequest ( response : DebugProtocol . ScopesResponse , args : DebugProtocol . ScopesArguments ) : void {
78
+ try {
79
+ const frame : FrameVariableReference = {
80
+ type : 'frame' ,
81
+ frameHandle : args . frameId ,
82
+ } ;
83
+ // const pins: ObjectVariableReference = {
84
+ // type: "object",
85
+ // varobjName: "__pins",
86
+ // frameHandle: 42000,
87
+ // }
88
+
89
+ response . body = {
90
+ scopes : [
91
+ // new Scope('Pins', this.variableHandles.create(pins), false),
92
+ new Scope ( 'Local' , this . variableHandles . create ( frame ) , false ) ,
93
+ new Scope ( 'Global' , GLOBAL_HANDLE_ID , false ) ,
94
+ new Scope ( 'Static' , STATIC_HANDLES_START + parseInt ( args . frameId as any , 10 ) , false )
95
+ ] ,
96
+ } ;
97
+
98
+ this . sendResponse ( response ) ;
99
+ } catch ( err ) {
100
+ this . sendErrorResponse ( response , 1 , err . message ) ;
101
+ }
102
+ }
103
+
104
+ protected async variablesRequest ( response : DebugProtocol . VariablesResponse , args : DebugProtocol . VariablesArguments ) : Promise < void > {
105
+ try {
106
+ response . body = {
107
+ variables : [ ] as DebugProtocol . Variable [ ]
108
+ } ;
109
+ const ref = this . variableHandles . get ( args . variablesReference ) ;
110
+ if ( args . variablesReference === GLOBAL_HANDLE_ID ) {
111
+ // Use hardcoded global handle to load and store global variables
112
+ response . body . variables = await this . variableHandler . getGlobalVariables ( ) ;
113
+ } else if ( args . variablesReference >= STATIC_HANDLES_START && args . variablesReference <= STATIC_HANDLES_FINISH ) {
114
+ // Use STATIC_HANDLES_START to shift the framehandles back
115
+ const frameHandle = args . variablesReference - STATIC_HANDLES_START ;
116
+ response . body . variables = await this . variableHandler . getStaticVariables ( frameHandle ) ;
117
+ } else if ( ref && ref . type === 'frame' ) {
118
+ // List variables for current frame
119
+ response . body . variables = await this . handleVariableRequestFrame ( ref ) ;
120
+ } else if ( ref && ref . varobjName === '__pins' ) {
121
+ response . body . variables = await this . variableHandler . handlePinStatusRequest ( ) ;
122
+ } else if ( ref && ref . type === 'object' ) {
123
+ // List data under any variable
124
+ response . body . variables = await this . handleVariableRequestObject ( ref ) ;
125
+ }
126
+ this . sendResponse ( response ) ;
127
+ } catch ( err ) {
128
+ this . sendErrorResponse ( response , 1 , err . message ) ;
129
+ }
130
+ }
131
+
65
132
}
0 commit comments