@@ -2639,50 +2639,86 @@ export class GDBDebugSession extends LoggingDebugSession {
2639
2639
this . sendResponse ( response ) ;
2640
2640
}
2641
2641
2642
- private async globalVariablesRequest ( response : DebugProtocol . VariablesResponse , args : DebugProtocol . VariablesArguments ) : Promise < void > {
2643
- const symbolInfo : SymbolInformation [ ] = this . symbolTable . getGlobalVariables ( ) ;
2644
-
2645
- const globals : DebugProtocol . Variable [ ] = [ ] ;
2642
+ private async updateOrCreateVariable (
2643
+ symOrExpr : string , gdbVarName : string , parentVarReference : number ,
2644
+ threadId : number , frameId : number , isFloating : boolean ) : Promise < DebugProtocol . Variable > {
2646
2645
try {
2647
- for ( const symbol of symbolInfo ) {
2648
- const varObjName = `global_var_${ symbol . name } ` ;
2649
- let varObj : VariableObject ;
2650
- try {
2651
- const changes = await this . miDebugger . varUpdate ( varObjName , - 1 , - 1 ) ;
2652
- const changelist = changes . result ( 'changelist' ) ;
2653
- changelist . forEach ( ( change ) => {
2646
+ let varObj : VariableObject ;
2647
+ let outOfScope = false ;
2648
+ try {
2649
+ const changes = await this . miDebugger . varUpdate ( gdbVarName , threadId , frameId ) ;
2650
+ const changelist = changes . result ( 'changelist' ) ;
2651
+ for ( const change of changelist || [ ] ) {
2652
+ const inScope = MINode . valueOf ( change , 'in_scope' ) ;
2653
+ if ( inScope === 'true' ) {
2654
2654
const name = MINode . valueOf ( change , 'name' ) ;
2655
2655
const vId = this . variableHandlesReverse [ name ] ;
2656
2656
const v = this . variableHandles . get ( vId ) as any ;
2657
- v . applyChanges ( change ) ;
2658
- } ) ;
2659
- const varId = this . variableHandlesReverse [ varObjName ] ;
2660
- varObj = this . variableHandles . get ( varId ) as any ;
2657
+ v . applyChanges ( change /*, variable.valueStr*/ ) ;
2658
+ } else {
2659
+ const msg = `${ symOrExpr } currently not in scope` ;
2660
+ await this . miDebugger . sendCommand ( `var-delete ${ gdbVarName } ` ) ;
2661
+ if ( this . args . showDevDebugOutput ) {
2662
+ this . handleMsg ( 'log' , `Expression ${ msg } . Will try to create again\n` ) ;
2663
+ }
2664
+ outOfScope = true ;
2665
+ throw new Error ( msg ) ;
2666
+ }
2661
2667
}
2662
- catch ( err ) {
2663
- try {
2664
- if ( err instanceof MIError && err . message === 'Variable object not found' ) {
2665
- varObj = await this . miDebugger . varCreate ( args . variablesReference , symbol . name , varObjName ) ;
2666
- const varId = this . findOrCreateVariable ( varObj ) ;
2667
- varObj . exp = symbol . name ;
2668
- varObj . id = varId ;
2668
+ const varId = this . variableHandlesReverse [ gdbVarName ] ;
2669
+ varObj = this . variableHandles . get ( varId ) as any ;
2670
+ }
2671
+ catch ( err ) {
2672
+ try {
2673
+ if ( outOfScope || ( err instanceof MIError && err . message === 'Variable object not found' ) ) {
2674
+ // Create variable in current frame/thread context. Matters when we have to set the variable */
2675
+ if ( isFloating ) {
2676
+ varObj = await this . miDebugger . varCreate ( parentVarReference , symOrExpr , gdbVarName ) ;
2669
2677
} else {
2670
- throw err ;
2678
+ varObj = await this . miDebugger . varCreate ( parentVarReference , symOrExpr , gdbVarName , '*' , threadId , frameId ) ;
2671
2679
}
2680
+ const varId = this . findOrCreateVariable ( varObj ) ;
2681
+ varObj . exp = symOrExpr ;
2682
+ varObj . id = varId ;
2683
+ } else if ( isFloating ) {
2684
+ throw err ;
2672
2685
}
2673
- catch ( err ) {
2686
+ }
2687
+ catch ( err ) {
2688
+ if ( isFloating ) {
2674
2689
if ( this . args . showDevDebugOutput ) {
2675
- this . handleMsg ( 'stderr' , `Could not create global variable ${ symbol . name } \n` ) ;
2690
+ this . handleMsg ( 'stderr' , `Could not create global/static variable ${ symOrExpr } \n` ) ;
2676
2691
this . handleMsg ( 'stderr' , `Error: ${ err } \n` ) ;
2677
2692
}
2678
2693
varObj = null ;
2694
+ } else {
2695
+ throw err ;
2679
2696
}
2680
2697
}
2698
+ }
2699
+ if ( isFloating && varObj ) {
2700
+ this . putFloatingVariable ( parentVarReference , symOrExpr , varObj ) ;
2701
+ }
2702
+ return varObj ?. toProtocolVariable ( ) ;
2703
+ }
2704
+ catch ( err ) {
2705
+ const ret : DebugProtocol . Variable = {
2706
+ name : symOrExpr ,
2707
+ value : `<${ err } >` ,
2708
+ variablesReference : 0
2709
+ } ;
2710
+ return ret ;
2711
+ }
2712
+ }
2681
2713
2682
- if ( varObj ) {
2683
- this . putFloatingVariable ( args . variablesReference , symbol . name , varObj ) ;
2684
- globals . push ( varObj . toProtocolVariable ( ) ) ;
2685
- }
2714
+ private async globalVariablesRequest ( response : DebugProtocol . VariablesResponse , args : DebugProtocol . VariablesArguments ) : Promise < void > {
2715
+ const symbolInfo : SymbolInformation [ ] = this . symbolTable . getGlobalVariables ( ) ;
2716
+ const globals : DebugProtocol . Variable [ ] = [ ] ;
2717
+ try {
2718
+ for ( const symbol of symbolInfo ) {
2719
+ const varObjName = `global_var_${ symbol . name } ` ;
2720
+ const tmp = await this . updateOrCreateVariable ( symbol . name , varObjName , args . variablesReference , - 1 , - 1 , true ) ;
2721
+ globals . push ( tmp ) ;
2686
2722
}
2687
2723
2688
2724
response . body = { variables : globals } ;
@@ -2744,46 +2780,8 @@ export class GDBDebugSession extends LoggingDebugSession {
2744
2780
2745
2781
for ( const symName of staticNames ) {
2746
2782
const varObjName = this . createStaticVarName ( fHash , symName ) ;
2747
- let varObj : VariableObject ;
2748
- try {
2749
- const changes = await this . miDebugger . varUpdate ( varObjName , - 1 , - 1 ) ;
2750
- const changelist = changes . result ( 'changelist' ) ;
2751
- changelist . forEach ( ( change ) => {
2752
- const name = MINode . valueOf ( change , 'name' ) ;
2753
- const vId = this . variableHandlesReverse [ name ] ;
2754
- const v = this . variableHandles . get ( vId ) as any ;
2755
- v . applyChanges ( change ) ;
2756
- } ) ;
2757
- const varId = this . variableHandlesReverse [ varObjName ] ;
2758
- varObj = this . variableHandles . get ( varId ) as any ;
2759
- }
2760
- catch ( err ) {
2761
- try {
2762
- // Not all static variables found via objdump can be found with gdb. Happens
2763
- // with function/block scoped static variables (objdump uses one name and gdb uses another)
2764
- // Try to report what we can. Others show up under the Locals section hopefully.
2765
- if ( err instanceof MIError && err . message === 'Variable object not found' ) {
2766
- varObj = await this . miDebugger . varCreate ( args . variablesReference , symName , varObjName ) ;
2767
- const varId = this . findOrCreateVariable ( varObj ) ;
2768
- varObj . exp = symName ;
2769
- varObj . id = varId ;
2770
- } else {
2771
- throw err ;
2772
- }
2773
- }
2774
- catch ( err ) {
2775
- if ( this . args . showDevDebugOutput ) {
2776
- this . handleMsg ( 'stderr' , `Could not create static variable ${ file } :${ symName } \n` ) ;
2777
- this . handleMsg ( 'stderr' , `Error: ${ err } \n` ) ;
2778
- }
2779
- varObj = null ;
2780
- }
2781
- }
2782
-
2783
- if ( varObj ) {
2784
- this . putFloatingVariable ( args . variablesReference , symName , varObj ) ;
2785
- statics . push ( varObj . toProtocolVariable ( ) ) ;
2786
- }
2783
+ const tmp = await this . updateOrCreateVariable ( symName , varObjName , args . variablesReference , threadId , frameId , true ) ;
2784
+ statics . push ( tmp ) ;
2787
2785
}
2788
2786
2789
2787
response . body = { variables : statics } ;
@@ -2835,42 +2833,9 @@ export class GDBDebugSession extends LoggingDebugSession {
2835
2833
await this . miDebugger . sendCommand ( `stack-select-frame --thread ${ threadId } ${ frameId } ` ) ;
2836
2834
stack = await this . miDebugger . getStackVariables ( threadId , frameId ) ;
2837
2835
for ( const variable of stack ) {
2838
- try {
2839
- const varObjName = this . createStackVarName ( variable . name , args . variablesReference ) ;
2840
- let varObj : VariableObject ;
2841
- try {
2842
- const changes = await this . miDebugger . varUpdate ( varObjName , threadId , frameId ) ;
2843
- const changelist = changes . result ( 'changelist' ) ;
2844
- changelist . forEach ( ( change ) => {
2845
- const name = MINode . valueOf ( change , 'name' ) ;
2846
- const vId = this . variableHandlesReverse [ name ] ;
2847
- const v = this . variableHandles . get ( vId ) as any ;
2848
- v . applyChanges ( change /*, variable.valueStr*/ ) ;
2849
- } ) ;
2850
- const varId = this . variableHandlesReverse [ varObjName ] ;
2851
- varObj = this . variableHandles . get ( varId ) as any ;
2852
- }
2853
- catch ( err ) {
2854
- if ( err instanceof MIError && err . message === 'Variable object not found' ) {
2855
- // Create variable in current frame/thread context. Matters when we have to set the variable */
2856
- varObj = await this . miDebugger . varCreate ( args . variablesReference , variable . name , varObjName , '*' , threadId , frameId ) ;
2857
- const varId = this . findOrCreateVariable ( varObj ) ;
2858
- varObj . exp = variable . name ;
2859
- varObj . id = varId ;
2860
- }
2861
- else {
2862
- throw err ;
2863
- }
2864
- }
2865
- variables . push ( varObj . toProtocolVariable ( ) ) ;
2866
- }
2867
- catch ( err ) {
2868
- variables . push ( {
2869
- name : variable . name ,
2870
- value : `<${ err } >` ,
2871
- variablesReference : 0
2872
- } ) ;
2873
- }
2836
+ const varObjName = this . createStackVarName ( variable . name , args . variablesReference ) ;
2837
+ const tmp = await this . updateOrCreateVariable ( variable . name , varObjName , args . variablesReference , threadId , frameId , false ) ;
2838
+ variables . push ( tmp ) ;
2874
2839
}
2875
2840
response . body = {
2876
2841
variables : variables
0 commit comments