一、问题起因

  系统发布上线后,有时会发生错误,那么错误的记录就很重要,它对于错误的排查和问题的发现有着重要的作用,通常我们采取的方式为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 = ; 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 - ])
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 

对文件名、行号,这也是我们需要的啊。

三、问题解决

  没办法,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.51cto.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界面)

网站发布IIS后堆栈追踪无法获取出错的行号的更多相关文章

  1. Web项目或WCF发布IIS后,如何通过VS2010调试

    在做项目的时候,例如WCF服务一般都会将WCF服务承载于控制台应用程序,或者WinForm窗体应用程序,因为这样可以直接在服务代码上打断点,然后就可以调试了.但是项目已经发布了,当然这里我用的本机进行 ...

  2. Win7系统下网站发布IIS配置

    *本帖为个人收集贴,所有版权归:西门的后花园 http://ons.me* Technorati 标记: IIS,网站,发布,配置 一.首先是安装IIS.打开控制面板,找到“程序与功能”,点进去 二. ...

  3. C#获取堆栈信息,输出文件名、行号、函数名、列号等

    命名空间:System.Diagnostics 得到相关信息: StackTrace st = new StackTrace(new StackFrame(true));StackFrame sf = ...

  4. 【POI】修改已存在的xls,新添一列后,再保存本文件+获取最大有效行号+获取单元格内容

    使用POI版本: ① ② ③ ④ package com.poi.dealXlsx; import java.io.File; import java.io.FileInputStream; impo ...

  5. 关于 X509Certificate2 程序发布IIS后找不到文件路径的问题

    有很多支付类.物联网等平台调用接口时需要用到证书: 通过X509Certificate2 类加载证书在程序发布之后发现无法找到证书路径,但是通过文件查找方法又可以检测到该文件. X509Certifi ...

  6. 网上都没有提到的教程:python捕获异常后,怎么输出错误文件和行号

    1.假设输出不存在的变量 a try: print(a) except NameError as e: print('发生错误的文件:', e.__traceback__.tb_frame.f_glo ...

  7. c++/c 获取cpp文件行号跟文件名

    编译器内置宏: 先介绍几个编译器内置的宏定义,这些宏定义不仅可以帮助我们完成跨平台的源码编写,灵活使用也可以巧妙地帮我们输出非常有用的调试信息. ANSI C标准中有几个标准预定义宏(也是常用的): ...

  8. javascript——获取列表选择行的列值

    表格布局 方法 代码 $("#send").click(function(){ //获取选择的行号 n= $('input:radio[name="radio" ...

  9. Mvc网站发布到IIS

    网站发布步骤: 这部分是转载文章 在此标明出处,以前有文章是转的没标明的请谅解,因为有些已经无法找到出处,或者与其它原因. 如有冒犯请联系本人,或删除,或标明出处. 因为好的文章,以前只想收藏,但连接 ...

随机推荐

  1. crosses initialization of “XXX” 的问题

    在switch-case中定义了变量,用g++编译的时候报错crosses initialization of “XXX” ,在网上一查,说是gcc要求变量的定义不能位于goto之后 将变量定义放在s ...

  2. Java多线程之ThreadLocal总结2

    ThreadLocal是什么 早在JDK 1.2的版本中就提供Java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁地 ...

  3. HDU1565_方格取数(1)

    给一个数字方阵,你要从中间取出一些数字,保证相邻的两个数字不同时被取出来,求取出来的最大的和是多少? 建立图模型,对于行列的和为奇数的格子,建立一条从原点到达这个点的边,对于行列和为偶数的格子,建立一 ...

  4. bzoj1036 [ZJOI2008]树的统计Count(树链剖分)

    Description 一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w.我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. Q ...

  5. 【uoj#37/bzoj3812】[清华集训2014]主旋律 状压dp+容斥原理

    题目描述 求一张有向图的强连通生成子图的数目对 $10^9+7$ 取模的结果. 题解 状压dp+容斥原理 设 $f[i]$ 表示点集 $i$ 强连通生成子图的数目,容易想到使用总方案数 $2^{sum ...

  6. springmvc+mybatis 处理图片(一):上传图片

    一直觉得上传图片文件之类的很难,所以最后才处理图片,发现也并没有那么难,开始正文. 思路:将前台上传的file存到MutipartFile类型字段中,再将MulipartFile转换为pojo类中的b ...

  7. 第五周linux学习笔记

    第五章 系统调用 5.1 与内核通信 系统调用在用户空间进程和硬件设备之间添加了一个中间层.该层主要作用有三个. 它为用户空间提供了一种硬件的抽象接口. 系统调用保 证了系统的毡定和安全. 在第 3 ...

  8. 一些程序OEP入口特征

    声明: 1.本文中使用的例子来源于吾爱破解的官方教程第一课中的无壳例子,本人利用空闲时间挨个进行查看并截图纪录下来 2.欢迎补充讨论 一些程序OEP入口特征 一.       AMS程序 1.载入PE ...

  9. 设置CMD默认路径

    用CMD每一次都得切换路径,很麻烦. 所以,需要设置一下CMD默认路径: 1.打开注册表编辑器(WIN+R打开运行.输入regedit) 2.定位到: “HKEY_CURRENT_USER\Softw ...

  10. Python【time】模块

    import timeprint(type(11.234))print("输出结果为时间戳,float类型:",time.time())print("输出结果为本地时间元 ...