远程调试

1 安装

Remote Debug下载地址:https://visualstudio.microsoft.com/zh-hans/downloads/?rr=https://docs.microsoft.com/en-us/visualstudio/debugger/remote-debugging?view=vs-2019
vs2022的一些调试技巧——远程调试&线程检查&性能检查-LMLPHP
选择下载进行安装,最后管理员运行。
vs2022的一些调试技巧——远程调试&线程检查&性能检查-LMLPHP
查看目标机运行所使用的端口号
vs2022的一些调试技巧——远程调试&线程检查&性能检查-LMLPHP

2.调试

1.调试->附加进程
修改对应的目标主机的端口和IP地址
vs2022的一些调试技巧——远程调试&线程检查&性能检查-LMLPHP

2.选中对应的进程点击附加
vs2022的一些调试技巧——远程调试&线程检查&性能检查-LMLPHP

3.我们贴上一段代码,代码会死循环打印一个自增的数

static void Main(string[] args)
{
    int i = 0;
    while (true) 
    {
        Console.WriteLine(++i);
        Thread.Sleep(1000);
    }
}

我们在目标主机运行起来,然后在本地利用源码进行远程调试,并且加上一个断点。发现断点进来了,并且程序不再打印,则调试成功。
vs2022的一些调试技巧——远程调试&线程检查&性能检查-LMLPHP

线程调试

我们来调查一个死锁。
先实现一个简单的死锁程序:声明两个锁对象,并且用两个线程各自占用一个锁,再去索要另外一个锁,形成死锁。

private static object _lock = new object();
        private static object _lock_1 = new object();
        static void Main(string[] args)
        {
            var task1 = Task.Run(DeadLock);
            var task2 = Task.Run(DeadLock_1);

            Task.WaitAll(task1,task2);
            Console.WriteLine("Hello, World!");
        }

        private static void DeadLock()
        {
            lock (_lock)
            {
                Thread.Sleep(200);
                lock (_lock_1)
                {
                    Console.WriteLine("DeadLock");
                }
            }
        }

        private static void DeadLock_1()
        {
            lock (_lock_1)
            {
                Thread.Sleep(200);
                lock (_lock)
                {
                    Console.WriteLine("DeadLock_1");
                }
            }
        }

运行程序之后,将程序中断
vs2022的一些调试技巧——远程调试&线程检查&性能检查-LMLPHP
点击调试->窗口->线程
可以看到两个工作线程,双击可以查看该线程中断时所处的位置。从而可以分析线程是否阻塞在这里,是否是形成问题的关键。
vs2022的一些调试技巧——远程调试&线程检查&性能检查-LMLPHP

vs2022的一些调试技巧——远程调试&线程检查&性能检查-LMLPHP

性能调试

点击调试->性能追踪(Performance Profiler)
vs2022的一些调试技巧——远程调试&线程检查&性能检查-LMLPHP

我们来实现一个CPU密集型的代码

        static async Task Main(string[] args)
        {
            await MultiRunning();
            SomeThing();
            Console.WriteLine("Hello, World!");
        }

        //启动20个线程
        static async Task MultiRunning()
        {
            Thread[] tasks = new Thread[20];
            foreach (var index in Enumerable.Range(0, tasks.Length))
            {
                tasks[index] = new Thread(() =>
                {
                    while (true)
                    {
                        int a = 1;
                        Thread.Sleep(200);
                    }
                });
            }

            int i = 0;
            await Parallel.ForEachAsync(tasks, (task, source) =>
            {
                i++;
                task.Start();
                return ValueTask.CompletedTask;
            });

            Console.WriteLine("执行了" + i);
        }

        static void SomeThing()
        {
            while (true)
            {
                Console.WriteLine("I AM Alive");
                Thread.Sleep(200);
            }
        }

我们使用Performance Profiler对启动项目的CPU进行监控。
vs2022的一些调试技巧——远程调试&线程检查&性能检查-LMLPHP
vs2022的一些调试技巧——远程调试&线程检查&性能检查-LMLPHP
当我们觉得程序运行的差不多了,我们可以点击停止搜集,然后visual studio会给我们生成一些分析数据
vs2022的一些调试技巧——远程调试&线程检查&性能检查-LMLPHP
点击打开详情,然后根据函数来分析占用的CPU,默认也是按照函数所占用的CPU时间片来进行排序。选择我们程序的函数,双击Main函数,可以看到里面的方法各自的占用,从而判断找出高CPU的函数。
vs2022的一些调试技巧——远程调试&线程检查&性能检查-LMLPHP

以此类推,如果需要寻找高IO的根源点,也可以使用VS自带的Performace Profiler来追踪代码的执行性能。

06-06 01:47