@@ -1167,27 +1167,66 @@ export class CodeLLDBDebuggerFacade extends GenericDebuggerFacade {
11671167 }
11681168 }
11691169
1170+ isAmbiguousError ( err : Error ) {
1171+ /*
1172+ * Error message is '... (reference|call) to XXX is ambiguous ...',
1173+ * but check only 'is ambiguous' since first part varies and
1174+ * perform another check for first part will be too expensive.
1175+ */
1176+ return err . message . indexOf ( 'is ambiguous' ) !== - 1 ;
1177+ }
1178+
1179+ isVoidReturnError ( err : Error ) {
1180+ return err . message === 'unknown error' ;
1181+ }
1182+
11701183 async evaluate ( expression : string , frameId : number | undefined , context ?: string , noReturn ?: boolean ) : Promise < dap . EvaluateResponse > {
1171- /* TODO: handle 'is ambiguous' error - make another attempt */
1184+ /*
1185+ * CodeLLDB has many expression evaluators: simple, python and native.
1186+ * https://github.com/vadimcn/codelldb/blob/master/MANUAL.md#expressions
1187+ *
1188+ * Default is 'simple' (changed in settings), but we use only native,
1189+ * so add '/nat' for each expression for sure.
1190+ */
1191+ expression = `/nat ${ expression } ` ;
1192+
11721193 try {
1173- /*
1174- * CodeLLDB has many expression evaluators: simple, python and native.
1175- * https://github.com/vadimcn/codelldb/blob/master/MANUAL.md#expressions
1176- *
1177- * Default is 'simple' (changed in settings), but we use only native,
1178- * so add '/nat' for each expression for sure.
1179- */
1180- expression = `/nat ${ expression } ` ;
1194+ try {
1195+ return await super . evaluate ( expression , frameId , context ) ;
1196+ } catch ( err ) {
1197+ if ( ! ( err instanceof Error ) ) {
1198+ throw err ;
1199+ }
1200+
1201+ /*
1202+ * CodeLLDB do not like 'static inline' functions and some other
1203+ * symbols which are defined multiple times. But even though it
1204+ * complains about it only for the first time and all subsequent
1205+ * calls succeed.
1206+ *
1207+ * Earlier this retry was in caller code, but too many parts now
1208+ * leak this knowledge, so it should be a better idea to handle
1209+ * it here.
1210+ */
1211+ if ( ! this . isAmbiguousError ( err ) ) {
1212+ throw err ;
1213+ }
1214+ }
1215+
11811216 return await super . evaluate ( expression , frameId , context ) ;
11821217 } catch ( err ) {
11831218 if ( ! ( err instanceof Error ) ) {
11841219 throw err ;
11851220 }
11861221
1187- if ( noReturn && err . message === 'unknown error' ) {
1222+ if ( noReturn && this . isVoidReturnError ( err ) ) {
11881223 /*
11891224 * CodeLLDB don't like 'void' returning expressions and
1190- * throws such strange errors, but call actually succeeds
1225+ * throws such strange errors, but call actually succeeds.
1226+ *
1227+ * Below we have retry logic, but it exists only for 'ambiguous'
1228+ * error, not for this one. I think we can get whole bunch of
1229+ * errors
11911230 */
11921231 return {
11931232 memoryReference : '' ,
@@ -1198,7 +1237,6 @@ export class CodeLLDBDebuggerFacade extends GenericDebuggerFacade {
11981237 }
11991238
12001239 this . handleCodeLLDBDebuggerError ( err ) ;
1201-
12021240 throw err ;
12031241 }
12041242 }
0 commit comments