如何在记录异常日志的时候包含源代码文件名和行号等信息
前言
作为一个程序员,你的相当一部分时间可能会用在调试。不知道大家是否同意,异常处理(Exception Handling)是一个看似简单,但是又极难做好的工作。当然,现在已经有一些业界经验以及框架(例如Enterprise Library中的Exception Handling Application Block)可供参考和使用,这些框架可以帮助我们较为灵活地配置,处理或者记录异常。我今天要跟大家分享的一个话题是,如何在记录异常的时候,包含源代码文件名和行号等有用信息。如果有这些信息,我们将能更加简单地定位到问题所在。
案例演示
为了讲解这个内容,我准备了一个简单的项目来做演示,如下所示
实际上,这个Solution中有两个项目,一个是作为组件的ClassLibrarySample
1: using System;
2:
3: namespace ClassLibrarySample
4: {
5: public class Test
6: {
7: public void MyMethod(int a, int b) {
8: try
9: {
10: Console.WriteLine(b/a);
11: }
12: catch (Exception ex)
13: {
14: Console.WriteLine(ex.Message);
15: }
16: }
17: }
18: }
另一个是作为调用程序的ConsoleApplicationSample
1: using System;
2:
3: namespace ConsoleApplicationSample
4: {
5: class Program
6: {
7: static void Main(string[] args)
8: {
9: var t = new ClassLibrarySample.Test();
10: t.MyMethod(0, 1);//这个调用会出错,因为会发生除零错误
11: Console.Read();
12: }
13: }
14: }
这个程序运行起来肯定就是会报告异常,然后被捕捉到,我们在主程序上面可以看到如下的输出
我们都知道,这样的异常消息可能对我们帮助不是很大,尤其是如果源文件中代码有成百上千行,那么如果不能快速定位到可能是哪一行出了这个异常,那么看起来调试和排错都会很难。
那么是否有办法在异常消息中,得到源代码文件的一些信息呢?事实上是可以做到的,你只要像下面这样修改即可:使用了StackTrace这个类型
1: using System;
2: using System.Diagnostics;
3:
4: namespace ClassLibrarySample
5: {
6: public class Test
7: {
8: public void MyMethod(int a, int b) {
9: try
10: {
11: Console.WriteLine(b/a);
12: }
13: catch (Exception ex)
14: {
15: Console.WriteLine(ex.Message);
16: //通过如下代码来记录异常详细的信息
17: var trace = new StackTrace(ex, true).GetFrame(0);
18: Console.WriteLine("文件名:{0},行号:{1},列号:{2}", trace.GetFileName(), trace.GetFileLineNumber(), trace.GetFileColumnNumber());
19: }
20: }
21: }
22: }
这样一来,我们再进行调试的时候,就可以看到更加详细的信息了。
大家可能会很好奇,这个信息是怎么给我们的呢?其实,要想实现这个功能,必须满足一个前提条件,就是必须有ClassLibrarySample这个组件对应的调试符号文件(pdb)。
如果我将这个文件删除掉,会怎么样呢?
我们看到,如果没有pdb文件,则输出的信息是空白的。
所以,如果你想使用这个技术来记录这些与源代码有关的详细信息,需要确保在部署应用程序的时候,将有关组件的pdb文件也一起部署。
如果是私有部署的话,那么要做到这一点是不难的,打包的时候,将pdb文件一起包含进去就可以了。但如果这个组件是公有部署(部署到GAC) 的话,就需要额外的一些步骤。
为了将程序集部署到GAC,我们首先需要对其进行强名称签名。
然后,通过gacutil这个命令行工具,可以手工地将其添加到GAC中
接下来,为了让主程序使用GAC中这个组件,而不是程序根目录下面的那个。我们需要对引用做一个设置:Copy local设置为false
再次运行主程序的话,我们会得到如下的输出
还是没有与源代码有关的详细信息,这是因为注册到GAC的程序集默认都是没有pdb文件的。他们一般在下面这样的目录里面
【备注】.NET Framework 4.0这个版本中对于GAC的路径做了调整,不再是原先的c:\windows\assembly目录了
所以,如果需要的话,你可以将pdb文件,手工(或者通过脚本)复制到这个目录,例如
这样的话,就可以在运行主程序的时候,得到与源代码有关的详细信息了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
2010-07-12 《实践与思考》系列连载(4)——众说纷纭“架构师”
2009-07-12 .NET : Func委托和Action委托
2009-07-12 如何在ASP.NET页面中使用异步任务(PageAsyncTask)
2009-07-12 如何为javascript代码编写注释以支持智能感知
2009-07-12 CSS应用及其优先级问题
2009-07-12 .NET : 在VS2008中计算代码度量值
2009-07-12 什么是高清视频