@@ -155,13 +155,14 @@ describe('multithread', async function () {
155155 expect ( varnameToValue . get ( 'name' ) ) . to . contain ( name ) ;
156156 }
157157 {
158- // Make sure we can get variables for frame 0,
159- // the contents of those variables don't actually matter
160- // as the thread will probably be stopped in a library
161- // somewhere waiting for a semaphore
162- // This is a test for #235
158+ // Depending on which frame the top of the stack is,
159+ // make sure we are getting the expected variables for that
160+ // frame.
161+ // This is a test for https://github.com/eclipse-cdt-cloud/cdt-gdb-adapter/issues/235
162+ const topOfStackId = stack . body . stackFrames [ 0 ] . id ;
163+ const topOfStackName = stack . body . stackFrames [ 0 ] . name ;
163164 const scopes = await dc . scopesRequest ( {
164- frameId : stack . body . stackFrames [ 0 ] . id ,
165+ frameId : topOfStackId ,
165166 } ) ;
166167 const vr = scopes . body . scopes [ 0 ] . variablesReference ;
167168
@@ -174,12 +175,36 @@ describe('multithread', async function () {
174175 variable . value ,
175176 ] )
176177 ) ;
177- // Make sure we aren't getting the HelloWorld frame's variables.
178- // The calling method (in glibc or similar) may end up with a local
179- // variable called thread_id, if so, update this heuristic
180- // We could be stopped PrintHello, so we don't perform the check
181- // if that is the case
182- if ( stack . body . stackFrames [ 0 ] . id !== printHelloFrameId ) {
178+
179+ // Check that thread_id is the correct value and that one other
180+ // local variable in the method exists.
181+ // We don't check local variable values because it may not be
182+ // correct yet, for example if the program stopped before assigning
183+ // the value to thread_id_plus_1 testing it against thread_id + 1
184+ // would lead to rare, but intermittent, test failures.
185+ if ( topOfStackName === 'inner_method' ) {
186+ expect ( varnameToValue . get ( 'thread_id' ) ) . to . equal (
187+ idInProgram . toString ( )
188+ ) ;
189+ expect ( varnameToValue . get ( 'thread_id_plus_1' ) ) . to . not . be
190+ . undefined ;
191+ } else if ( topOfStackName === 'recursive' ) {
192+ expect ( varnameToValue . get ( 'thread_id' ) ) . to . equal (
193+ idInProgram . toString ( )
194+ ) ;
195+ expect ( varnameToValue . get ( 'depth' ) ) . to . not . be . undefined ;
196+ } else if ( topOfStackName === 'PrintHello' ) {
197+ expect ( varnameToValue . get ( 'thread_id' ) ) . to . equal (
198+ idInProgram . toString ( )
199+ ) ;
200+ expect ( varnameToValue . get ( 'void_arg' ) ) . to . not . be . undefined ;
201+ } else {
202+ // The top of the stack is probably (and normally) not
203+ // in our code, but rather in the various semaphore code
204+ // therefore make sure our "thread_id" is not visible
205+ // It could happen that the sempahore (or related code) ends
206+ // up with a local called "thread_id" in the future - if so,
207+ // this will fail and needs to be updated
183208 expect ( varnameToValue . get ( 'thread_id' ) ) . to . be . undefined ;
184209 }
185210 }
0 commit comments