I have a StackOverFlowException problem in an ASP.NET MVC application and I can not seem to figure out what might be causing this. I installed Elmah as suggested in another topic on the same problem, but it can not capture because the application pool ends up falling and in this way the system is no longer operable nor to generate a log ). I saw that there is a tool called ADPlus , but I do not know how to configure it and I did not find an article that answered me.
As a necessity, I started to generate logs from all requests to see if it was some specific page that generated the error and when the application I would try to check which of requests before the time the pool crashed (which I check for Event Viewer strong> IIS ) might be causing this, but I could not simulate it. I do not know if it is a running operation that keeps running for a long time until it gives this type of exception.
I would like someone to help me with how to use some type of ADPlus parser and try to figure out the source of this problem.
Update 17/05
Global.asax:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngine());
//Adicionei este filtro para capturar todos os requests para tentar descobrir com o horário (quando o pool caísse) se era alguma página que estava dando algum loop infinito, mas não consegui
RegisterGlobalFilters(GlobalFilters.Filters);
}
//Metodo que captura erros a nivel de sistema
void Application_Error(object sender, EventArgs e)
{
Exception exc = Server.GetLastError();
if (exc.Message.Contains("NoCatch") || exc.Message.Contains("maxUrlLength"))
return;
var desc = string.Empty;
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
desc += "User Identity = " + User.Identity.GetUserId() + Environment.NewLine;
}
desc += "IP = " + HttpContext.Current.Request.UserHostAddress + Environment.NewLine;
//Gero um logo para erros a nível de sistema (mas para o stackoverflow nem funciona, pois o pool cai e a aplicação também
ExceptionHelper.CriarArquivoExceptionServer(exc.Message, desc);
if (exc.GetType() == typeof(HttpException))
{
HttpContext.Current.Response.Redirect("http://www.site.com.br");
}
Response.Write("A página que você tentou acessar não pode ser exibida. Acesse o site www.site.com.br\n");
Server.ClearError();
}
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new FilterAllActions());
}
//este e para um problema que estava tendo de autenticação entre http/https (mas ja foi resolvido através do stackoverflow mesmo)
void Session_Start(object sender, EventArgs e)
{
var cookie = Request.Cookies.Get(".AspNet.ApplicationCookie");
//aqui só estou forçando a flag Secure do cookie de autenticação a ser "false" para poder compartilhar-lo entre http/https
if (cookie != null && cookie.Secure == true)
{
cookie.Secure = false;
}
}
}
}
Requests Write Filter (called by RegisterGlobalFilters in Global.asax):
public class FilterAllActions : IActionFilter, IResultFilter
{
//A ideia e gravar um log antes de executar um request, pois se eu for verificar o horário que o pool caiu, posso ter noção de qual página próximo a queda algum usuário acessou (tudo isso para garantir se não é alguma página que está sofrendo de loop infinito e gerando o overflow)
public void OnActionExecuting(ActionExecutingContext filterContext)
{
var action = filterContext.ActionDescriptor.ActionName;
var url = "Inicio: " + "Metodo: " + HttpContext.Current.Request.HttpMethod + " | URL: " + HttpContext.Current.Request.Url.AbsoluteUri + " | Action: " + action + " | " + "IP: " + ObterEnderecoIp() + " | " + "Id: " + filterContext.HttpContext?.User?.Identity?.Name + " | Browser: " + HttpContext.Current.Request.Browser.Browser;
ExceptionHelper.CriarArquivoRequestServer(url);
//
}
//A ideia deste metodo é garantir que o método foi finalizado
public void OnActionExecuted(ActionExecutedContext filterContext)
{
var action = filterContext.ActionDescriptor.ActionName;
var url = "Fim: " + "Metodo: " + HttpContext.Current.Request.HttpMethod + " | URL: " + HttpContext.Current.Request.Url.AbsoluteUri + " | Action: " + action + " | " + "IP: " + ObterEnderecoIp() + " | " + "Id: " + filterContext.HttpContext?.User?.Identity?.Name + " | Browser: " + HttpContext.Current.Request.Browser.Browser;
ExceptionHelper.CriarArquivoRequestServer(url);
//
}
// Busco o endereço desta forma pois todos os requests batem em um firewall antes de chegar no site
protected string ObterEnderecoIp()
{
var userIpAddress = string.Empty;
try
{
var forwardedFor = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
userIpAddress = String.IsNullOrWhiteSpace(forwardedFor) ? HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"] : forwardedFor.Split(',').Select(s => s.Trim()).First();
}
catch
{
//
userIpAddress = HttpContext.Current.Request.UserHostAddress ?? string.Empty;
}
return userIpAddress;
}
}