一:背景

1. 讲故事

每次项目预交付的时候,总会遇到各种奇葩的坑,我觉得有必要梳理一下以及如何快速解决的,让后来人避避坑,这篇就聊聊自己的所闻所遇:

  • 我去,本地环境代码跑的哧溜,上了测试环境出问题
  • 我去, 第三方提供的 dll 跑出 bug 了

二:两个大坑的解决方案

1. 本地环境没问题,上了测试出问题

相信很多朋友都有我这样类似的遭遇,明明程序代码,配置文件都一样,挪了一个窝就出问题,你说气人不,既然问题出了那怎么快速解决呢? 对,就是用调试,但程序部署在 centos 上,送一个 visualstudio 上去也不现实,在这种限制级条件下还想调试怎么办呢?不错,可以上远程调试,然后就很快查到了测试机器中的某一个环境变量搞错了,事情的来龙去脉搞清楚了,接下来就看看怎么实现 local 到 centos 的 远程调试。

1) 测试代码

为了方便演示,我就在 Action 中读取 strategy 环境变量。


public class HomeController : Controller
{
public IActionResult Index()
{
ViewBag.strategy = Environment.GetEnvironmentVariable("strategy"); return View();
}
}

2) 安装 SSH

要远程调试,需要在远端机安装 SSH,因为后面附加进程调试 就要借助 SSH 打通。


yum install openssh-server unzip curl

安装完成后,就能看到 22 端口已启动


[root@localhost data]# netstat -tlnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1126/sshd
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 3037/cupsd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1739/master
tcp6 0 0 :::22 :::* LISTEN 1126/sshd
tcp6 0 0 ::1:631 :::* LISTEN 3037/cupsd
tcp6 0 0 ::1:25 :::* LISTEN 1739/master

3) 程序的发布配置

发布配置上,第一个要确保是 debug 版本,第二个要确保是 可移植模式 (Portable), 如下图:

4) 使用附加进程调试

在菜单栏依次选择:Debug -> Attach To Process,然后填写 ssh 需要的各种信息,如下图:

点击 Connect 后,就能看到远端机器的 dotnet程序 进程号,选择该进程进行附加,在 Select Code Type 中选择 Nanaged (.NET Core for Unix)即可,如下图:

5) 顺利调试

在 浏览器中键入: http://192.168.142.130/Home/Index ,可以看到我的 C# 代码被命中,也顺利的拿到了远端机器的 环境变量,问题也就迎刃而解。

2. 第三方 dll 出 bug 了

调试程序除了使用 F9 进行调试,相信也有不少朋友知道断点是可以编辑的,比如说:设置表达式断点,过滤器断点,命中次数断点,动作断点,下如图:

第一个问题就来了,这些花式断点,你真的会用吗?真的会经常用吗?

让我来回答的话,不到万不得已我是不会用的,我更愿意在代码中加入利于调试的测试语句,原因有三点:

  • 更加灵活

这个显而易见,在面板中设置条件相比用纯语句设置要麻烦得多,点来点去,而且还要条件叠加,复杂的很,我是不喜欢。

  • 功能强大

编辑面板上只有简单的并且关系,而且各个条件还是同级别的,无法做到各个条件的或者关系以及层级或者递归的包含关系,所以。。。没办法。。。

  • 更易于保存

这个就有意思了,在断点上右键是弹出编辑面板,点击左键是关闭断点,问题就出在这里,经常由于手贱,本想点右键结果点了左键 。。。。 好不容易设置好的条件没了。。。真的没了,从此以后,路转黑。如下图:

那这么说断点编辑真的没用吗? 我觉得只有在不能修改语句的调试场景下能够大显身手,比如我遇到的调试厂家封装的dll,哈哈,既然说到了断点,我就用 dnspy 演示几个断点给大家复习一下吧!

1) 测试代码

为方便演示,用 for 循环案例是最好的。


public static void Main(string[] args)
{
var sum = 0; for (int i = 0; i < 10000; i++)
{
sum += i;
} Console.WriteLine($"sum={sum}");
}

2) 我希望在 sum = 1035 的时候命中断点

这个用条件表达式断点就可以了,非常简单,如下所示:

3) 找到所有能够被 1800 整除的数,并且记录下当时的 i 和 sum 值

这里就可以用到 Action 断点的日志记录,在 for 循环迭代中,不需要中断断点,只需记录某一个特定状态下当前的 i 和 sum 的值,对调试代码非常有帮助,如下图:

三:总结

总的来说这两个经验也算我一步一步踩坑过来的,如果能帮到你就更好了,本篇就聊这么多,下篇再见!

更多高质量干货:参见我的 GitHub: dotnetfly

一路踩坑,被迫聊聊 C# 代码调试技巧和远程调试的更多相关文章

  1. 安卓手机移动端Web开发调试之Chrome远程调试(Remote Debugging)

    一.让安卓打debug模式的apk包 二.将电脑中的chrome升级到最新版本,在chrome浏览器地址栏中输入chrome://inspect/#devices: 在智能手机还未普及时,移动设备的调 ...

  2. 移动应用调试之Inspect远程调试

    移动应用调试之Inspect远程调试 一.准备工作 chrome浏览器,建议最新版本 如果你点击inspect打开的DevTools窗口一片空白,且刷新无效时,那极有可能是由于被墙的缘故. 二.Ins ...

  3. Visual Studio 调试系列12 远程调试部署在远程计算机IIS上的ASP.NET应用程序

    系列目录     [已更新最新开发文章,点击查看详细] 要调试已部署到IIS的ASP.NET应用程序,请在部署应用程序的计算机上安装并运行远程工具,然后从Visual Studio附加到正在运行的应用 ...

  4. Eclipse进行远程调试(Tomcat远程调试)

    1.配置tomcat Linxu系统: tomcat/bin/catalina.sh或者startup.sh开始处中增加如下内容: declare -x CATALINA_OPTS="-Xd ...

  5. Visual Studio 调试系列11 远程调试

    系列目录     [已更新最新开发文章,点击查看详细] 你可以调试已部署在另一台计算机的 Visual Studio 应用程序. 要进行此操作,可使用 Visual Studio 远程调试器. 01 ...

  6. JavaScript调试技巧之断点调试

    首先,在各个浏览器中,断点调试支持的最好的当然是Firefox,Firefox不仅可以使用Firebug调试页面js脚本,还可以用高级调试工具例如JavaScript Debugger (Venkma ...

  7. VS2012远程调试(winform+web 远程调试)

    VS2012远程调试   一.调试WinFrom 程序 安装rtools_setup_x64 下载 配置Remote 启动Remote debugger 默认端口4016,选择工具-〉选项,选择 无身 ...

  8. VS本地调试 Visual Studio远程调试监视器(MSVSMON.EXE)的32位版本不能用于调试64位进程或64位转储

    vs2017 调试一致都没啥问题,今天莫名报这个错误,感觉好奇怪,网上搜索了半天也没解决,最后看着错误信息感觉很诡异,我本地调试你给我启动远程调试监测器干嘛,localhost也访问不了,ping了一 ...

  9. pycharm快捷键、配置virtualenv环境,配置django调试,配置远程调试

    pycharm安装和首次使用 http://blog.csdn.net/chenggong2dm/article/details/9365437 快捷键: 找文件.代码.引用相关 1.双击shift ...

随机推荐

  1. py004.python的逻辑运算,随机数及判断语句if,elif,else

    判断语句又称 "分支语句" if判断语句的格式: if 条件1: 条件1满足时,执行的代码 -- # 前面有缩进4个空格 elif 条件2: 条件2满足时,执行的代码 -- # 前 ...

  2. Power Designer建模之餐饮在线点评系统——业务处理模型

    餐饮在线点评系统除查看会员促销活动.查看站内消息等简单业务流程外,相对复杂的业务流程包括管理员注册餐厅,发布餐厅信息,餐厅信息主要包括特色菜.促销活动.团购活动和优惠券信息. 餐厅信息发布后,用户可以 ...

  3. Lyndon words学习笔记

    Lyndon words 定义: 对于一个字符串\(S\),若\(S\)的最小后缀是其本身,则\(S\)为一个\(lyndon\)串; 记为\(S\in L\); 即: \[S \in L \begi ...

  4. 087 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 01 封装的概念和特点

    087 01 Android 零基础入门 02 Java面向对象 02 Java封装 01 封装的实现 01 封装的概念和特点 本文知识点:封装的概念和特点 说明:因为时间紧张,本人写博客过程中只是对 ...

  5. Arduino 模拟引脚

    Arduino的模拟引脚的引用,网上不错的一篇文章 参考:http://blog.sina.com.cn/s/blog_156e62ef90102xjio.html 模拟引脚 本文是对于Arduino ...

  6. 系统编程-文件IO-IO处理方式

    IO处理五种模型 .

  7. RHSA-2019:0201-低危: systemd 安全更新

    [root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 修复命令: 使用root账号登陆She ...

  8. centos7搭建docker环境

    Docker简介 Docker是一种虚拟化技术,用来将你的应用程序及其依赖的环境一起打包成一个镜像发布,使得在任何地方都能获得相同的运行环境. Docker 是一个开源项目,诞生于 2013 年初,最 ...

  9. spring boot:使用多个线程池实现实现任务的线程池隔离(spring boot 2.3.2)

    一,为什么要使用多个线程池? 使用多个线程池,把相同的任务放到同一个线程池中,可以起到隔离的作用,避免有线程出错时影响到其他线程池,例如只有一个线程池时,有两种任务,下单,处理图片,如果线程池被处理图 ...

  10. 选择SaaS平台的那些事

    将近一年多没有更新博客和自己的订阅号.除了本身有点懒之外,也有幸在上半年花了一些时间考出了CISSP.最近也在研究云平台相关的一些课题. 写这篇文章本身是因为在工作中经常有IT乃至业务的同事会问及企业 ...