设为首页 收藏本站
查看: 1179|回复: 0

[经验分享] 网站发布IIS后堆栈追踪无法获取出错的行号

[复制链接]

尚未签到

发表于 2015-8-15 11:15:44 | 显示全部楼层 |阅读模式
  一、问题起因
  系统发布上线后,有时会发生错误,那么错误的记录就很重要,它对于错误的排查和问题的发现有着重要的作用,通常我们采取的方式为Log日志文件记录和数据库错误记录。文本不会讨论错误记录的方式以及如何记录记录,而是更关注如何更好地获取错误的具体信息,换句话说如何能够更好地提供错误信息的描述以便快速解决问题。
  通常错误的记录类似如下的写法 (不保证正确,这只是一种方式)



private string BuildStackTrace(Exception _exp)
{
Exception exp = _exp;
StringBuilder sb = new StringBuilder();
sb.Append("---- Stack Trace ----");
sb.Append("\r\n|");
sb.Append(exp.GetType().ToString());
sb.Append("|\r\n");
sb.Append(EnhancedStackTrace(exp));
while (exp.InnerException != null)
{
exp = exp.InnerException;
sb.Append("\r\n|");
sb.Append(exp.GetType().ToString());
sb.Append("|\r\n");
sb.Append(EnhancedStackTrace(exp));
}
return sb.ToString();
}


public static string EnhancedStackTrace(Exception exp)
{
return EnhancedStackTrace(new StackTrace(exp, true));
//return exp.StackTrace;
}


public static string EnhancedStackTrace(StackTrace st)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < st.FrameCount; i++)
{
StackFrame sf = st.GetFrame(i);
sb.Append(StackFrameToString(sf));
}
sb.Append(Environment.NewLine);
return sb.ToString();
}


public static string StackFrameToString(StackFrame sf)
{
StringBuilder sb = new StringBuilder();
MemberInfo mi = sf.GetMethod();
sb.Append("   ");
sb.Append(mi.DeclaringType.Namespace);
sb.Append(".");
sb.Append(mi.DeclaringType.Name);
sb.Append(".");
sb.Append(mi.Name);
sb.Append("(");
foreach (ParameterInfo param in sf.GetMethod().GetParameters())
{
sb.Append(param.ParameterType.Name);
sb.Append(" ");
sb.Append(param.Name);
if (param ==
sf.GetMethod().GetParameters()[sf.GetMethod().GetParameters().Length - 1])
continue;
sb.Append(", ");
}
sb.Append(")");
sb.Append("<br/>");
sb.Append("       ");
if (string.IsNullOrEmpty(sf.GetFileName()))
{
sb.Append("(unknown file)");
sb.Append(": N ");
sb.Append(String.Format("{0:#00000}", sf.GetNativeOffset()));
}
else
{
sb.Append(System.IO.Path.GetFileName(sf.GetFileName()));
sb.Append(": line ");
sb.Append(String.Format("{0:#0000}", sf.GetFileLineNumber()));
sb.Append(", col ");
sb.Append(String.Format("{0:#00}", sf.GetFileColumnNumber()));
if (sf.GetILOffset() != StackFrame.OFFSET_UNKNOWN)
{
sb.Append(", IL ");
sb.Append(String.Format("{0:#0000}", sf.GetILOffset()));
}
}
sb.Append("<br/>");
return sb.ToString();
}
  上面的方法在本地运行的时候没有任何问题,我们能获得我们需要的关于错误的详细信息,尤其是页面、方法和行号,但是当发布IIS后,我们就无法获取到具体的错误消息,仅仅返回System.Web.HttpUnhandledException之类的消息,这对于我们排查错误而言根本没用。
  
  二、问题分析
  发布后web.config文件做了一些关于Session的修改,模式有InProc变成了SQLServer,难道是序列化出了问题,可是ASP.NET本身的 Exception 和StackTrace 都是序列化的,保存至Session没有问题啊



[Serializable]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(_Exception))]
[ComVisible(true)]
public class Exception : ISerializable, _Exception

[Serializable]
[ComVisible(true)]
public class StackTrace
  把本地的Session模式也改成SQLServer并Debug,结果发现问题了:new StackTrace(exp, true)根本没有生成正确的StackTrace,所以下面的堆栈追踪也就没有了下文,这是为什么,笔者也不解,希望知道的童鞋能告知。算了此路不通换一种方式,直接使用Exception.StackTrace,使用Exception属性总该可以了吧,果然获得了我想要的东西。再次发布IIS,问题又来了,这次虽然错误消息"进步"了,类似



at Web.Pages.ContractMgt.ContractMgt.ContractInfo.btnRefresh_Click(Object sender, EventArgs e)
  但是为什么后面的没了,不是应该是如下的吗?



at Web.Pages.ContractMgt.ContractMgt.ContractInfo.btnRefresh_Click(Object sender, EventArgs e) in D:\newWorkSpace\src\projectlms\Web\Pages\ContractMgt\ContractMgt\ContractInfo.aspx.cs:line 860
  对文件名、行号,这也是我们需要的啊。
  三、问题解决
  没办法,Google吧,在查阅了一些资料后,偶发现了原因,原来是在发布到IIS的时候我把编译生成的PDB文件给删了,此奥!PDB这个文件主要会存储对应模块(dll或者exe)内部的所有符号,以及符号对应的地址、文件名和行号。原来如此。那赶紧加回去吧,再次运行,还是不行,靠,奔溃了,继续Google,网上有人说是web.config的这个配置会影响,直接删除再试



<authentication mode="Windows" />
<identity impersonate="true" />
  终于这次可以了,但是为什么上面的配置会影响啊,同样不解。
  另还有一个重要的问题,在发布正式库的时候能包含PDB文件吗?继续Google

1. 是否会影响性能
  http://www.wintellect.com/blogs/jrobbins/do-PDB-files-affect-performance (Do PDB Files Affect Performance?)
  The executive summary answer: no, generating PDB files will have no impact on performance whatsoever. As for references that I can point you too, I haven't found any on the web that answer the exact question so let me take both .NET and native development in turn.
  
  http://stackoverflow.com/questions/1270986/do-pdbs-slow-down-a-release-application (Do .pdbs slow down a release application?)
  http://developer.iyunv.com/art/201306/397712.htm (.NET PDB文件到底是什么?)
  对于.NET应用程序来说,生成PDB文件不会影响编译器的优化,所以也完全不会影响应用的性能
  总结:不会影响性能,只会对于生成的程序集中的一个DebuggableAttribute的属性产生影响

2. 是否会影响安全
  http://stackoverflow.com/questions/1307482/whats-the-risk-of-deploying-debug-symbols-pdb-file-in-a-production-environmen (What's the risk of deploying debug symbols (pdb file) in a production environment?)
  http://stackoverflow.com/questions/933883/are-there-any-security-issues-leaving-the-pdb-debug-files-on-the-live-servers
  貌似也不会影响安全
  
  但是要记住,做如下设定(VS2010界面)
DSC0000.png

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-99292-1-1.html 上篇帖子: 【转】启动停止重启IIS的命令 下篇帖子: 关闭或修改 IIS 443 端口
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表