visual studio 调试增强,实现一行代码打印调用栈

news2024/11/20 4:27:44

如何主动打印调用栈?如果是Java、Js,那么很简单,三行就能实现。但 VisualStudio 就复杂多了。如果不下断点,那么只能在崩溃的时候被动查看。

而使用 Backward-Cpp ,只需在项目中拖入一个hpp文件,就可以主动打印。但默认输出是 stderr,无法在 VisualStudio 的 output 窗口看到任何信息。全网搜索半小时后,才从另外零星的代码片段中推得,需要将 stringstream 作为输出对象:

std::stringstream stream;

using namespace backward;
StackTrace st; st.load_here(32);
Printer p; p.print(st, stream);

然后打印 stream 内容至 VisualStudio 输出窗口:

::OutputDebugStringA(stream.str().c_str());

默认输出格式比较零散,下面分享一些强化的方法。

一、调整 Backward-Cpp 参数

backward.hpp为我们引入了 StackTrace 和 Printer, 这两个对象的参数都可以调整(开发者比较用心)。前者的构造参数是数字,代表打印深度,默认32层,一般8层即可。

StackTrace 还有一个有用的方法:skip_n_firsts(数字),指示跳过前面几层的打印,建议跳过两层,这样就可以自写util方法包绕,实现一行代码打印调用栈,然后直接从感兴趣的的方开始打印。

Printer 对象则可配置多个成员变量:

  1. 控制是否打印代码片段,建议关闭,因为开启后调用栈特别长,不利于定位上下游
    bool snippet = true;
  2. 控制是否逆序打印。默认逆序不用修改,和Java等同一个顺序(和Python不一样),这样就可以在打印调用栈前,输出一段关键字,然后调试运行,在 output 窗口搜索关键字,离关键字最近的下方就是最近的函数调用点了。
    bool reverse = true;
    请添加图片描述

二、魔改打印格式,适配VisualStudio

Backward-Cpp 的默认打印格式不是上图这样的,虽然可以很漂亮,但没有适配 VisualStudio,无法双击定位文件。文件名前面不能有非空字符,需要照着这个pull请求魔改:

os << "\n";//Need a newline or it does not work
    os << source_loc.filename << "(" << source_loc.line << "):";//This exact format is required
    os << " line "  << source_loc.line << ", in " << source_loc.function;
#else
	  os << indent << "Source \"" << source_loc.filename << "\", line "
		  << source_loc.line << ", in " << source_loc.function;

此外,我还去掉了 #序号 前缀,使得调用栈更加紧凑:

//os << "#" << std::left << std::setw(2) << trace.idx << std::right;

三、用 vhk 实现快捷刷新调试器

修改代码后,经常需要重新开始调试。若只有一个解决方案还好,但如果是多模块项目,比如重新编译duilib这一界面的静态库后,需要重新调试实际程序,于是需要以下两个重复步骤——

  1. 查找底部点击底部****毫无高亮效果的任务栏,切换至程序项目的窗口。
  2. 再点击VisualStudio顶部****小小的"Restart"按钮

"Restart"按钮默认快捷键是 ctrl+shift+f5,需要双手操作,很不方便。其实,F5按键默认是运行,但都处于调试状态了,为何不用F5直接“刷新”调试器?这样一键多用,岂不美哉!

可以用ahk拦截F5,然后根据 VisualStudio 标题是否含有(Running)子串分发不同的快捷键:

#IfWinActive ahk_exe devenv.exe
$F5::
	WinGetTitle,S
	;消息(S, "w450")
	StringGetPos, idx, S, (Running)
	if(idx > 0) {
		Send ^+{F5}
	} else {
		Send {F5} 
	}
return

更激进地,还可以右击左边框启动调试器:

(需要设置Debug.start快捷键为Ctrl+Shift+Alf+F5,Debug.start竟然和Debug.Restart相互冲突,不能设置为同一个,不知咋想的)

~RButton::
	MouseGetPos, xpos, ypos
	if(xpos < 10) {			
		SendInput ^+{F5}
		SendInput ^+!{F5}
	}
return

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/191392.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[Android]ProgressBar进度条

ProgressBar ProgressBar是进度条控件&#xff0c;ProgressBar的应用场景很多&#xff0c;比如用户登录时&#xff0c;后台发送请求&#xff0c;以及进行等待服务器返回信息等一些比较耗时的操作。这个时候如果没有提示&#xff0c;用户可能会以为程序崩溃了或手机死机了&#…

【数据结构】1.2 数据结构的基本概念和术语

文章目录1. 数据、数据元素、数据项和数据对象2. 数据结构逻辑结构的种类存储结构的种类3. 数据类型和抽象数据类型数据类型抽象数据类型概念小结1. 数据、数据元素、数据项和数据对象 数据&#xff08;Data&#xff09; 能输入计算机且能被计算机处理的各种符号的集合。 信息…

AcWing1074. 二叉苹果树(树形DP +分组背包)

AcWing1074. 二叉苹果树&#xff08;树形DP 分组背包&#xff09;一、问题二、分析1、状态表示2、状态转移3、循环设计三、代码一、问题 二、分析 这道题是一个在数上做分组背包问题的模型&#xff0c;那么为什么是分组背包呢&#xff1f;作者在之前的文章中进行过详细地讲解&…

VUE2常用知识

1、Vue的基本原理 【】当一个Vue实例创建时&#xff0c;Vue会遍历data中的属性&#xff0c;用 Object.defineProperty&#xff08;vue3.0使用proxy &#xff09;将它们转为 getter/setter&#xff0c;并且在内部追踪相关依赖&#xff0c;在属性被访问和修改时通知变化。 每个组…

工时管理:按工作时间还是完成的任务来跟踪员工的生产力?

据中国社科院的一项调查显示&#xff1a;我国有86%的职场人都患有拖延症&#xff1b;50%的人不到最后一刻绝不开始工作&#xff1b;13%的人没有人催不能完成工作。 拖延症对小型或成长型企业的影响是很大的&#xff0c;毕竟&#xff0c;任务永远不会因为逃避或简单地坐在那里而…

【Linux】信号保存、信号处理、可重入函数、volatile关键字、SIGCHLD信号

目录 一、信号保存 1.1 信号相关的概念名词 1.2 在内核中的表示 1.3 sigset_t与操作函数 1.4 信号设定 二、信号处理 2.1 内核空间与用户空间 2.2 内核态和用户态 2.3 信号的捕捉流程 2.4 sigaction 函数 三、可重入函数 四、volatile 五、SIGCHLD信号 一、信号保…

当今主流的网络服务应用

文件传输协议 主机之间传输文件是IP网络的一个重要功能&#xff0c;如今人们可以方便地使用网页、邮箱进行文件传输。 然而在互联网早期&#xff0c;Web&#xff08;World Wide Web&#xff0c;万维网&#xff09;还未出现&#xff0c;操作系统使用命令行的时代&#xff0c;…

webpack前端应用之基础打包

目录 前言&#xff1a;初识 Webpack 5 一、前端工程化 1、webpack ​ &#xff08;2&#xff09;主要功能&#xff1a; 2、webpack的使用&#xff1a;配置文件所需要的信息&#xff08;五大配置属性&#xff09; 3、示例 强调&#xff1a; 4、webpack中使用的loader 二…

【Java基础】003 -- Java基础概念(计算机的存储规则)

目录 计算机的存储规则 1、什么是二进制&#xff1f; 2、为什么计算机要使用二进制存储数据&#xff1f; 3、进制之间可以转换吗&#xff1f; 4、码表&#xff08;Text文本&#xff09; 5、图片数据 6、声音数据 计算机的存储规则 在计算机中&#xff0c;任意的数据都是…

java集成RSA非对称加密数据传输

使用场景: 前端请求后端接口时如:登录接口,这时候需要传账号密码到后端接口请求这样就会暴露请求的数据。RSA非对称加密分公钥和私钥,公钥将数据进行加密,私钥对加密的数据进行解密 (当然前端最好是封装一下不要暴露出来公钥) 代码实现: 1、RSA工具类(或访问http:…

大数据舆情监控应用平台,TOOM大数据舆情监控系统的作用

大数据舆情监控应用是利用大数据技术对社会舆情的收集、分析、挖掘和展示的工具。它通常会收集和分析各种社交媒体、新闻媒体、博客等信息&#xff0c;以了解舆情动态和趋势。大数据舆情监控应用可以帮助企业和政府了解市场和社会动态&#xff0c;为决策提供支持。然而&#xf…

聚观早报 |比亚迪预计去年营收超4200亿元;美股三大指数集体收跌

今日要闻&#xff1a;比亚迪预计去年营收超 4200 亿元&#xff1b;美股三大指数集体收跌&#xff1b;王凤英正式加入小鹏汽车出任总裁&#xff1b;苹果计划在印度生产 25% 的 iPhone 手机&#xff1b;LVMH老板放狠话坚决打击代购行为比亚迪预计去年营收超 4200 亿元 1 月 30 日…

(Java高级教程)第四章必备前端基础知识-第三节3:JavaScript之DOM和BOM

文章目录一&#xff1a;WebAPI概述二&#xff1a;DOM&#xff08;1&#xff09;获取元素&#xff08;2&#xff09;事件&#xff08;3&#xff09;操作元素A&#xff1a;获取&#xff08;修改&#xff09;元素内容B&#xff1a;获取&#xff08;修改&#xff09;元素属性C&…

LeetCode 刷题系列 -- 108. 将有序数组转换为二叉搜索树

给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 高度平衡 二叉搜索树。高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。示例 1&#xff1a;输入&#xff1a;nums [-10,-3,0,5,9]输出&a…

粒子群优化(PSO)算法例题实现

目录 一、实验要求 二、算法流程 三、案例实现及结果 完整程序&#xff1a; 一、实验要求 二、算法流程 粒子群算法流程&#xff1a; 1、初始化&#xff1a;初始化粒子群&#xff1b;给每个粒子赋予初始位置和速度 2、计算适应值&#xff1a;根据适应度函数&#xff0c;计…

新范式+新标准=世界级产品|StarRocks年度总结

岁序常易&#xff0c;华章日新。虎年即将落幕&#xff0c;雄关漫道&#xff0c;我们携手社区斗志昂扬&#xff0c;并肩虎跃雄关。兔年新岁将至&#xff0c;黎明破晓&#xff0c;我们协力社区蓄势待发&#xff0c;昂首共赴新程。值此送虎迎兔的新春佳节之际&#xff0c;感恩与St…

电子技术——MOS放大器的DC偏置

电子技术——MOS放大器的DC偏置 正如前几节我们学习的&#xff0c;MOS放大器的小信号模型的参数取决于正确的DC偏置&#xff0c;这个步骤称为偏置设计。一个好的偏置设计要满足一个稳定的漏极DC电流 IDI_DID​ 和设置正确的 VDSV_{DS}VDS​ 保证MOS管在放大信号的时候处在饱和区…

Qt StyleSheet介绍

文章目录前言纠错技巧可以使用 , 号来同时指明多个同一类型控件的样式表qss注释前言 本文主要以这篇博客为基础。添加一些自己使用的心得和使用样式表的一些技巧 纠错 ID选择器这里类型选择器可以省略&#xff0c;因为每个控件的objectName是不一样的&#xff0c;所以无需指定…

高性能消息队列中间件MQ

毕业后工作半年&#xff0c;在自己的讲课中需要介绍消息队列&#xff0c;以前在大学也有经常接触message queen&#xff0c;但却还不够深入了解掌握&#xff0c;这次写个专门针对mq的文章理清头绪。 以下是学习mq的知识框架&#xff0c;我会不定时更新补充 RabbitMQ概念_MQ 消…

TwinCAT3串口通讯EL6021模块使用-和串口调试助手自由协议通讯

目录 一、简介 二、环境介绍 三、接线连接 四、创建TwinCAT3程序工程 1、IO扫描和参数设置 2、创建PLC程序 &#xff08;1&#xff09;库文件添加 &#xff08;2&#xff09;创建任务和程序 &#xff08;3&#xff09;变量关联 &#xff08;4&#xff09;重新激活工程、运…