@@ -381,13 +381,20 @@ export class StepContext {
381381 * Name of function which frame we are currently observing.
382382 */
383383 currentFunctionName ?: string ;
384+
385+ /*
386+ * Whether is it safe for not get elements of Bitmapset.
387+ * Main concern are breakpoints in bitmapset.c
388+ */
389+ isSafeToObserveBitmapset ?: boolean ;
384390
385391 reset ( ) {
386392 this . isSafeToAllocateMemory = undefined ;
387393 this . rtable . rtable = undefined ;
388394 this . rtable . waiter = undefined ;
389395 this . rtable . exists = false ;
390396 this . currentFunctionName = undefined ;
397+ this . isSafeToObserveBitmapset = undefined ;
391398 }
392399}
393400
@@ -4020,17 +4027,6 @@ export class ArraySpecialMember extends RealVariable {
40204027 * Bitmapset variable
40214028 */
40224029class BitmapSetSpecialMember extends NodeVariable {
4023- /*
4024- * List of functions that we are using for bitmapset evaluation.
4025- * We need to ensure, that no breakpoints set on them, otherwise
4026- * we encounter infinite loop
4027- */
4028- private static evaluationUsedFunctions = [
4029- 'bms_next_member' ,
4030- 'bms_first_member' ,
4031- 'bms_is_valid_set' ,
4032- ] ;
4033-
40344030 constructor ( args : RealVariableArgs ) {
40354031 super ( 'Bitmapset' , args ) ;
40364032 }
@@ -4088,38 +4084,41 @@ class BitmapSetSpecialMember extends NodeVariable {
40884084
40894085 return true ;
40904086 }
4091-
4092- safeToObserve ( ) {
4087+
4088+ isBreakpointDangerous ( bp : vscode . Breakpoint ) {
40934089 /*
4094- * Fastest way I found is just to iterate all breakpoints and check
4095- * - no bp in bitmapset.c source code for line breakpoints
4096- * - no bp for bms_next_member function for function breakpoints
4097- *
4098- * I have found only these 2 subclasses of breakpoints.
4099- * Seems that it is enough .
4090+ * Fastest way is just to iterate all breakpoints and check if
4091+ * breakpoint is dangerous, meaning that if we will stop, then can
4092+ * end up in infinite loop or precondition (state) can be violated.
4093+ *
4094+ * For now such breakpoints includes all functions inside bitmapset.c -
4095+ * main file with all Bitmapset manipulation logic .
41004096 */
4101- for ( const bp of vscode . debug . breakpoints ) {
4102- if ( ! bp . enabled ) {
4103- continue ;
4104- }
4097+ if ( ! bp . enabled ) {
4098+ return false ;
4099+ }
41054100
4106- if ( bp instanceof vscode . SourceBreakpoint ) {
4107- if ( bp . location . uri . path . endsWith ( 'bitmapset.c' ) ) {
4108- logger . info ( 'found breakpoint at bitmapset.c - set elements not shown' ) ;
4109- return false ;
4110- }
4111- } else if ( bp instanceof vscode . FunctionBreakpoint ) {
4112- /*
4113- * Need to check functions that are called to get set elements
4114- */
4115- if ( BitmapSetSpecialMember . evaluationUsedFunctions . indexOf ( bp . functionName ) !== - 1 ) {
4116- logger . info ( 'found breakpoint at %s - bms elements not shown' ,
4117- bp . functionName ) ;
4118- return false ;
4119- }
4120- }
4101+ if ( bp instanceof vscode . SourceBreakpoint ) {
4102+ return bp . location . uri . path . endsWith ( 'bitmapset.c' ) ;
41214103 }
4122- return true ;
4104+
4105+ if ( bp instanceof vscode . FunctionBreakpoint ) {
4106+ /*
4107+ * All Bitmapset functions have 'bms_' prefix.
4108+ * I can track which ones are dangerous, but if someday someone
4109+ * will create another dangerous function then logic will be broken,
4110+ * so add such simple check, so code will live longer.
4111+ */
4112+ return bp . functionName . startsWith ( 'bms_' ) ;
4113+ }
4114+
4115+ /* Other breakpoints must be safe */
4116+ return false ;
4117+ }
4118+
4119+ safeToObserve ( ) {
4120+ return this . context . step . isSafeToObserveBitmapset
4121+ ??= ! ! vscode . debug . breakpoints . find ( this . isBreakpointDangerous ) ;
41234122 }
41244123
41254124 async getSetElements ( members : Variable [ ] ) : Promise < number [ ] | undefined > {
0 commit comments