@@ -28,19 +28,13 @@ export interface SessionEvent<T extends DebugProtocol.Event> {
2828export type ContinuedEvent = SessionEvent < DebugProtocol . ContinuedEvent > ;
2929export type StoppedEvent = SessionEvent < DebugProtocol . StoppedEvent > ;
3030
31- export interface SessionRequest < T extends DebugProtocol . Request > {
31+ export interface SessionStackTrace {
3232 session : GDBTargetDebugSession ;
33- request : T ;
33+ threadId : number ;
34+ stackFrames : DebugProtocol . StackFrame [ ] ;
35+ totalFrames ?: number | undefined ;
3436}
3537
36- export interface SessionResponse < T extends DebugProtocol . Response > {
37- session : GDBTargetDebugSession ;
38- response : T ;
39- }
40-
41- export type StackTraceRequest = SessionRequest < DebugProtocol . StackTraceRequest > ;
42- export type StackTraceResponse = SessionResponse < DebugProtocol . StackTraceResponse > ;
43-
4438export type StackItem = vscode . DebugThread | vscode . DebugStackFrame | undefined ;
4539
4640export interface SessionStackItem {
@@ -50,6 +44,7 @@ export interface SessionStackItem {
5044
5145export class GDBTargetDebugTracker {
5246 private sessions : Map < string , GDBTargetDebugSession > = new Map ( ) ;
47+ private stackTraceRequests : Map < string , Map < number , number > > = new Map ( ) ;
5348
5449 private readonly _onWillStartSession : vscode . EventEmitter < GDBTargetDebugSession > = new vscode . EventEmitter < GDBTargetDebugSession > ( ) ;
5550 public readonly onWillStartSession : vscode . Event < GDBTargetDebugSession > = this . _onWillStartSession . event ;
@@ -72,28 +67,14 @@ export class GDBTargetDebugTracker {
7267 private readonly _onStopped : vscode . EventEmitter < StoppedEvent > = new vscode . EventEmitter < StoppedEvent > ( ) ;
7368 public readonly onStopped : vscode . Event < StoppedEvent > = this . _onStopped . event ;
7469
75- private readonly _onStackTraceRequest : vscode . EventEmitter < StackTraceRequest > = new vscode . EventEmitter < StackTraceRequest > ( ) ;
76- public readonly onStackTraceRequest : vscode . Event < StackTraceRequest > = this . _onStackTraceRequest . event ;
77-
78- private readonly _onStackTraceResponse : vscode . EventEmitter < StackTraceResponse > = new vscode . EventEmitter < StackTraceResponse > ( ) ;
79- public readonly onStackTraceResponse : vscode . Event < StackTraceResponse > = this . _onStackTraceResponse . event ;
70+ private readonly _onStackTrace : vscode . EventEmitter < SessionStackTrace > = new vscode . EventEmitter < SessionStackTrace > ( ) ;
71+ public readonly onStackTrace : vscode . Event < SessionStackTrace > = this . _onStackTrace . event ;
8072
8173 public activate ( context : vscode . ExtensionContext ) {
8274 const createDebugAdapterTracker = ( session : vscode . DebugSession ) : vscode . ProviderResult < vscode . DebugAdapterTracker > => {
8375 return {
84- onWillStartSession : ( ) => {
85- const gdbTargetSession = new GDBTargetDebugSession ( session ) ;
86- this . sessions . set ( session . id , gdbTargetSession ) ;
87- this . bringConsoleToFront . apply ( this ) ;
88- this . _onWillStartSession . fire ( gdbTargetSession ) ;
89- } ,
90- onWillStopSession : ( ) => {
91- const gdbTargetSession = this . sessions . get ( session . id ) ;
92- if ( gdbTargetSession ) {
93- this . sessions . delete ( session . id ) ;
94- this . _onWillStopSession . fire ( gdbTargetSession ) ;
95- }
96- } ,
76+ onWillStartSession : ( ) => this . handleOnWillStartSession ( session ) ,
77+ onWillStopSession : ( ) => this . handleOnWillStopSession ( session ) ,
9778 onDidSendMessage : ( message ) => this . handleOnDidSendMessage ( session , message ) ,
9879 onWillReceiveMessage : ( message ) => this . handleOnWillReceiveMessage ( session , message ) ,
9980 } ;
@@ -107,39 +88,81 @@ export class GDBTargetDebugTracker {
10788 ) ;
10889 } ;
10990
91+ private handleOnWillStartSession ( session : vscode . DebugSession ) : void {
92+ const gdbTargetSession = new GDBTargetDebugSession ( session ) ;
93+ this . sessions . set ( session . id , gdbTargetSession ) ;
94+ this . bringConsoleToFront ( ) ;
95+ this . _onWillStartSession . fire ( gdbTargetSession ) ;
96+ }
97+
98+ private handleOnWillStopSession ( session : vscode . DebugSession ) : void {
99+ const gdbTargetSession = this . sessions . get ( session . id ) ;
100+ if ( gdbTargetSession ) {
101+ this . sessions . delete ( session . id ) ;
102+ this . _onWillStopSession . fire ( gdbTargetSession ) ;
103+ }
104+ this . stackTraceRequests . delete ( session . id ) ;
105+ }
106+
110107 protected handleOnDidSendMessage ( session : vscode . DebugSession , message ?: DebugProtocol . ProtocolMessage ) : void {
111108 if ( ! message ) {
112109 return ;
113110 }
114111 if ( message . type === 'event' ) {
115- const event = message as DebugProtocol . Event ;
116- const gdbTargetSession = this . sessions . get ( session . id ) ;
117- switch ( event . event ) {
118- case 'continued' :
119- this . _onContinued . fire ( { session : gdbTargetSession , event } as ContinuedEvent ) ;
120- break ;
121- case 'stopped' :
122- this . _onStopped . fire ( { session : gdbTargetSession , event } as StoppedEvent ) ;
123- break ;
124- }
112+ this . handleEvent ( session , message as DebugProtocol . Event ) ;
125113 } else if ( message . type === 'response' ) {
126- const response = message as DebugProtocol . Response ;
127- const gdbTargetSession = this . sessions . get ( session . id ) ;
128- switch ( response . command ) {
129- case 'stackTrace' :
130- if ( ! gdbTargetSession ) {
131- break ;
132- }
133- this . _onStackTraceResponse . fire ( { session : gdbTargetSession , response } as StackTraceResponse ) ;
134- break ;
135- case 'launch' :
136- case 'attach' :
137- if ( response . success && gdbTargetSession ) {
138- this . _onConnected . fire ( gdbTargetSession ) ;
139- }
140- break ;
141- }
114+ this . handleResponse ( session , message as DebugProtocol . Response ) ;
115+ }
116+ }
117+
118+ private handleEvent ( session : vscode . DebugSession , event : DebugProtocol . Event ) : void {
119+ const gdbTargetSession = this . sessions . get ( session . id ) ;
120+ switch ( event . event ) {
121+ case 'continued' :
122+ this . _onContinued . fire ( { session : gdbTargetSession , event } as ContinuedEvent ) ;
123+ break ;
124+ case 'stopped' :
125+ this . _onStopped . fire ( { session : gdbTargetSession , event } as StoppedEvent ) ;
126+ break ;
127+ }
128+ }
129+
130+ private handleResponse ( session : vscode . DebugSession , response : DebugProtocol . Response ) : void {
131+ const gdbTargetSession = this . sessions . get ( session . id ) ;
132+ if ( ! gdbTargetSession ) {
133+ return ;
134+ }
135+ switch ( response . command ) {
136+ case 'launch' :
137+ case 'attach' :
138+ this . handleLaunchAttachResponse ( gdbTargetSession , response ) ;
139+ break ;
140+ case 'stackTrace' :
141+ this . handleStackTraceResponse ( gdbTargetSession , response as DebugProtocol . StackTraceResponse ) ;
142+ break ;
143+ }
144+ }
145+
146+ private handleLaunchAttachResponse ( gdbTargetSession : GDBTargetDebugSession , response : DebugProtocol . Response ) : void {
147+ if ( response . success ) {
148+ this . _onConnected . fire ( gdbTargetSession ) ;
149+ }
150+ }
151+
152+ private handleStackTraceResponse ( gdbTargetSession : GDBTargetDebugSession , response : DebugProtocol . StackTraceResponse ) : void {
153+ const stackTraceRequest = this . stackTraceRequests . get ( gdbTargetSession . session . id ) ;
154+ const threadId = stackTraceRequest ?. get ( response . request_seq ) ;
155+ stackTraceRequest ?. delete ( response . request_seq ) ;
156+ if ( ! response . success || threadId === undefined ) {
157+ return ;
142158 }
159+ const stackTrace = {
160+ session : gdbTargetSession ,
161+ threadId,
162+ stackFrames : response . body . stackFrames ,
163+ totalFrames : response . body . totalFrames
164+ } ;
165+ this . _onStackTrace . fire ( stackTrace ) ;
143166 }
144167
145168 protected handleOnWillReceiveMessage ( session : vscode . DebugSession , message ?: DebugProtocol . ProtocolMessage ) : void {
@@ -149,30 +172,41 @@ export class GDBTargetDebugTracker {
149172 if ( message . type === 'request' ) {
150173 const request = message as DebugProtocol . Request ;
151174 const gdbTargetSession = this . sessions . get ( session . id ) ;
175+ if ( ! gdbTargetSession ) {
176+ return ;
177+ }
152178 switch ( request . command ) {
153179 case 'launch' :
154180 case 'attach' :
155- {
156- const gdbTargetConfig = request . arguments as GDBTargetConfiguration ;
157- const cbuildRunFile = gdbTargetConfig . cmsis ?. cbuildRunFile ;
158- if ( cbuildRunFile && gdbTargetSession ) {
159- // Do not wait for it to keep the message flowing.
160- // Session class will do the waiting in case requests
161- // come early.
162- gdbTargetSession . parseCbuildRun ( cbuildRunFile ) ;
163- }
164- }
181+ this . handleLaunchAttachRequest ( gdbTargetSession , request ) ;
165182 break ;
166183 case 'stackTrace' :
167- if ( ! gdbTargetSession ) {
168- break ;
169- }
170- this . _onStackTraceRequest . fire ( { session : gdbTargetSession , request } as StackTraceRequest ) ;
184+ this . handleStackTraceRequest ( gdbTargetSession , request as DebugProtocol . StackTraceRequest ) ;
171185 break ;
172186 }
173187 }
174188 }
175189
190+ private handleLaunchAttachRequest ( gdbTargetSession : GDBTargetDebugSession , request : DebugProtocol . Request ) : void {
191+ const gdbTargetConfig = request . arguments as GDBTargetConfiguration ;
192+ const cbuildRunFile = gdbTargetConfig . cmsis ?. cbuildRunFile ;
193+ if ( cbuildRunFile ) {
194+ // Do not wait for it to keep the message flowing.
195+ // Session class will do the waiting in case requests
196+ // come early.
197+ gdbTargetSession . parseCbuildRun ( cbuildRunFile ) ;
198+ }
199+ }
200+
201+ private handleStackTraceRequest ( gdbTargetSession : GDBTargetDebugSession , request : DebugProtocol . StackTraceRequest ) : void {
202+ let stackTraceRequests = this . stackTraceRequests . get ( gdbTargetSession . session . id ) ;
203+ if ( stackTraceRequests === undefined ) {
204+ stackTraceRequests = new Map ( ) ;
205+ this . stackTraceRequests . set ( gdbTargetSession . session . id , stackTraceRequests ) ;
206+ }
207+ stackTraceRequests . set ( request . seq , request . arguments . threadId ) ;
208+ }
209+
176210 protected handleOnDidChangeActiveStackItem ( item : StackItem ) : void {
177211 const gdbTargetSession = item ?. session . id ? this . sessions . get ( item ?. session . id ) : undefined ;
178212 if ( ! gdbTargetSession ) {
0 commit comments