1

for effective debugging of my program, I tried to write function that gets an exception and emails me detailed reporting about the exception.

c# code:

 public static bool SendExceptionMail(Exception ex, string[] mail, string title)
    {
        StringBuilder builder = new StringBuilder();
        builder.Append("<table>");
        var st = new StackTrace(ex, true);
        builder.Append("<tr><td colspan='3'><h3>" + ex.GetType().Name + "</h3></td></tr>");
        builder.Append("<tr><td style='border: 1px solid #d8d8d8'>function name</td><td style='border: 1px solid #d8d8d8'>function path</td><td style='border: 1px solid #d8d8d8'>line number</td></tr>");
        StackFrame[] frames = st.GetFrames();
        for (int i = 0; i < frames.Length; i++)
        {
            builder.Append("<tr>");
            var frame = st.GetFrame;
            var line = frame.GetFileLineNumber();
            var name = frame.GetFileName();
            var functionName = frame.GetMethod().Name;
            builder.Append("<tr><td style='border: 1px solid #d8d8d8'>" + functionName + "</td><td style='border: 1px solid #d8d8d8'>" + name + "</td><td style='border: 1px solid #d8d8d8'>" + line + "</td></tr>");
            builder.Append("</tr>");
        }
        builder.Append("<tr><td colspan='3'>" + getInnerException(ex) + "</td></tr>");
        builder.Append("<tr><td colspan='3'>" + ex.Data + "</td></tr>");
        builder.Append("<tr><td colspan='3'>" + ex.StackTrace + "</td></tr>");
        builder.Append("<tr><td colspan='3'>" + DateTime.Now + "</td></tr>");
        builder.Append("</table>");
        return MailBll.Send("Exception in WS - " + frames[0].GetMethod().Name + " function", builder.ToString(), mail);
    }

private static string getInnerException(Exception ex)
{
        StringBuilder str = new StringBuilder();
        do
        {
            str.Append(ex.Message + "<br/>";
            ex = ex.InnerException;

        } while (ex != null);
        return str.ToString();
}

Clearing function:

public TranStatus Clearing(Entities.Tran tran, int projectId, string Link = null)
    {
        string d = DateTime.Now.ToString();
        try
        {
            sendTranDetails(tran, projectId, d);
            if (!string.IsNullOrEmpty(tran.Token) && !string.IsNullOrEmpty(tran.CreditNum))
            {
                tran.Token = "";
            }
            tran.Ip = "";
            if ((string.IsNullOrEmpty(tran.CreditNum) || tran.CreditNum.Length < 7) && string.IsNullOrEmpty(tran.Token))
            {
                return db.getCardErrorMassege("478");
            }

            if (!string.IsNullOrEmpty(tran.CreditNum) && tran.CreditNum.Length > 4)
            {
                if (tran.CreditNum.Substring(0, 4) == "0404" || tran.CreditNum.Substring(0, 4) == "0403")
                {
                    tmobile m = db.Mobiles.GetById(int.Parse(tran.Comment2));
                    return db.getCardErrorMassege("479");
                }
            }
            tterminal terminal;
            tproject p = db.GetProjectById(projectId);
            tran.ProjectNumber = p.sNumProject;
            terminal = db.GetterminalByProjectId(projectId);
            tran.Total = (int)tran.Total;
            tran.CompanyId = (int)p.iCompanyId;
            fixTran(tran);
            string intot = Dal.Transaction(terminal.sTerminalId.Substring(0, 7), PasswordBll.DecodeFrom64(terminal.sPasswordService), tran);
            string creditStatus = db.getcreditStatusById(intot);
            sendEmailTran(d, intot + " - " + creditStatus + "<br/>");
            return db.getCardErrorMassege(intot.Substring(0, 3));
        }
        catch (Exception ex)
        {
            MailBll.SendExceptionMail(ex);
            return db.getCardErrorMassege("484");
        }
    }

the function works ok, but there are some functions that I cannot get the original function that the exception was thrown from it.

for example: when I get exception of "IndexOutOfRangeException" I got this mail:

screenshot

but I don't see which line in Clearing function threw the exception and which file it was.

what can be the reason?

Community
  • 1
  • 1
Rachel Fishbein
  • 818
  • 2
  • 12
  • 29
  • That kind of information is stored in the debugging symbols, not the DLLs. You need to include the PDBs with your DLLs. As for missing frames, those calls might have been optimized away. It usually isn't too big of a deal when locating issues if you have the line numbers. – Luaan Apr 25 '17 at 13:42
  • 1
    It bombed inside an internal .NET Framework method. Even if you did get file+line info, that still would not be of any use to you given that you are not going to change the framework. The most important detail of an unhandled exception is the stack trace. That one tells you which of *your* methods got this wrong. You can't leave it out of your email, you *have* to include ex.StackTrace. Really rather best to not get fancy, simply use ex.ToString() to get everything you need. – Hans Passant Apr 25 '17 at 13:59
  • @Hans Passant, thanks, but I want to explain something. Clearing function is my own function. It appears in frames but line number is zero. What I want is to get line number that caused the exception. can I? Why I get function name but not line number in that function? – Rachel Fishbein Apr 26 '17 at 06:29
  • Project > Properties > Build tab, select the Release configuration, Advanced button > Debug Info = full. Rebuild and be sure to deploy the pdb files as well. Keep in mind that the info you now get is only an approximation. – Hans Passant Apr 26 '17 at 07:58
  • Where are you catching this exception? stackframes are not stored within the exception, so if you try {} catch in main, then there won't be any stack frames to examine – Neil Apr 26 '17 at 09:06
  • @Neil I am catching the exception inside Clearing function. all what I want is to know what line in the file that Clearing file is placed in it has caused the exception. – Rachel Fishbein Apr 26 '17 at 09:57
  • I think you need to post some more code. What you have posted should work, so there must be a problem in the code you are trying to check. – Neil Apr 26 '17 at 09:58
  • @Neil see my edit, I added Clearing function code. – Rachel Fishbein Apr 26 '17 at 10:42

1 Answers1

0

Debug or Release build?

If you are using a optimised (release) build, then the compiler is allowed to remove simple functions and in-line them. At this point, they won't have a stack frame. To get a good stack trace, you need to make sure no optimisations are enabled.

Neil
  • 11,059
  • 3
  • 31
  • 56