Me encontré con una situación en la que, de acuerdo con un minivolcado, ciertos archivos están causando un desbordamiento de pila en un analizador sintáctico de descenso recursivo. Lamentablemente, no puedo tener en mis manos un ejemplo de un archivo que hace esto para reproducir el problema (el cliente tiene problemas de confidencialidad), lo que me deja un poco desanimado al diagnosticar el problema real por el momento.¿Cómo puedo prevenir o recuperar un desbordamiento de pila en un subproceso de trabajador?
Claramente, el analizador necesita algo de atención, pero ahora mi principal prioridad es simplemente mantener el programa en ejecución. Como medida provisional, ¿qué puedo hacer para evitar que esto reduzca todo el programa?
Mi primera opción sería encontrar la manera de anticipar que me estoy quedando sin espacio en la pila para poder abortar con gracia el analizador antes de que ocurra el desbordamiento. No analizar el archivo es una opción aceptable. La segunda opción sería dejar que suceda, detectar el error y registrarlo, luego continuar con el resto de los datos.
El análisis está sucediendo en un bucle Parallel.ForEach()
. Estoy dispuesto a cambiar eso por otro enfoque si eso ayuda.
EDIT: Lo que sería realmente asesino es si tan sólo pudiera obtener el tamaño de la pila del subproceso actual y la posición del puntero de pila. es posible?
EDIT 2: Finalmente logré escurrir un archivo de muestra de alguien y atrapar el error en un depurador. Resulta que no es código que nos pertenece en absoluto, la excepción está en algún lugar en HtmlAgilityPack. Entonces parece que tendré que intentar encontrar una táctica completamente diferente.
No estoy seguro si esto ayudará ya que lo que causa el desbordamiento de la pila no está claro (el paralelismo no debería causar esto: la recursividad podría), pero ¿ha intentado usar 'ParallelOptions.MaxDegreeOfParallelism' para limitar la cantidad de llamadas simultáneas? – Jcl
Una opción es simplemente rastrear la "profundidad" actual del análisis sintáctico y fianza si es demasiado alta. – dlev
@dlev Me gustaría tener más detalles, sin embargo. La documentación de .NET sugiere eso, pero ¿cómo elijo una profundidad máxima apropiada, dado que tanto los marcos de pila como la pila de llamadas en su conjunto pueden tener diferentes tamaños? –