Capture Stackoverflowexception

Asked

Viewed 79 times

0

I have a problem with Stackoverflowexception in an application ASP.NET MVC and I can’t find what might be causing it. I installed the Elmah as suggested in another topic on the same problem, but it fails to capture, as the pool application 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 don’t know how to set up and I couldn’t find an article that would suit me.

As a necessity, I began to generate logs of all the requests to check if it was a specific page that caused the error and when the application fell, try to verify which of the requests previous to the time the pool fell (which I check by Event Viewer of IIS) could be causing this, but I couldn’t simulate it. I don’t know if it’s some high-powered operation that keeps running for quite a while until I make this kind of exception.

I wish someone could help me on how to use some kind of analyzer (Adplus preferably) and try to discover the origin 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;
            }
        }

    }
}

Filter for Recording Requests (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;
    }
}
  • You could share your content Global.asax (and also Startup.cs should you)? If you have no idea what it might be, I would start by trying to comment on various parts of the code until the problem stops.

1 answer

0

There is a lot of code that can generate exceptions, I advise you to use the Log4Net and go checking step by step of your algorithm. Unit tests also help a lot in these cases.

Configuring Log4net in a web application

Browser other questions tagged

You are not signed in. Login or sign up in order to post.