装软件的坑是什么?
遇到一个大坑,可能是3天都在坑里,爬不出去的致暗时刻。
会拼命上网看相关视频,会稍微多看些,以至于把这个问题的前后原理都照顾到,
看了几个视频后感觉都差不多流程但就是解决不了自己的问题,然后开始找完整的pdf技术手册、博客、帖子。
这段时间的神经会异常得紧张,对于技术点前后逻辑关系审核地特别严格,以至于用“苛刻”形容
对事物关系有极强的探求欲望,但是却异常地沉得下心,坐得住资源页页看下去
就像这块大石头,我一定要掀翻它!
第一天晚上睡觉的时候感觉很累很沮丧,感觉过不了这个坎
第二天晚上,感觉要么放弃该软件,要么放弃自己,觉得自己走投无路了
终于在第三天,解决了,豁然开朗。
人总是有硬着头皮的时刻,顶过那段时间就好
在那段时间里提高自己的分辨能力,解决事情的速度,增加阅历经验,以及坚定自己的内心。
当坑都踩过一遍,对这条技术路线也越来越了然于胸,分析地头头是道
靠编译器帮自己查语法错误
消灭笔误:编写适合程序员的键盘练习
if (常量==变量或表达式)
使用goto接力超长的if,switch
连续的if还是if elseif
多个条件的组合:精心的排版
多重括号的匹配
条件编译
各种const:不要纠结各种常量了,这个世界上唯一不变的就是变化。用APIWriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢!
查看宏展开后的.i文件:VC编译选项加/EP /P(项目、属性、配置属性、C/C++、预处理器、预处理到文件:是,预处理取消显示行号:是),重新编译,查看宏展开后对应的.i文件。gcc加-E
偶遇到莫名其妙的编译错误都是用“每次用/…/或#if 0…#endif注释掉不同部分再重新编译,直到定位到具体语法出错的位置。”的方法解决的。
附加包含路径、附加库路径、附加依赖库的设置。
靠调试器帮自己查逻辑错误
for/while语句后多余的分号
while/do while语句在语义上的歧义
条件断点
消息断点
数据断点
__asm int3或DebugBreak()断点
在内存窗口中观察数据的原始字节形态
Call Stack:崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止。
“给定一个小点的输入,完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门!
递归函数关注以下几个因素
·退出条件
·参数有哪些
·返回值是什么
·局部变量有哪些
·全局变量有哪些
·何时输出
·会不会导致堆栈溢出
语法糖越甜,编译调试查错越苦!
C++的隐藏调用:单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。
任务管理器、VMMap、Process Monitor、Process Explorer、GDI泄露检测工具、……
靠写日志帮自己查运营错误
CrashDump或Core的无力。
PDB的无力。
线上Debug的无力。
观察复杂数据的无力。
多线程调试的无力。
调试时序高度依赖代码的无力。
调试万年一遇非法数据的无力。
有时不将“调用函数名字+各参数值,进入函数后各参数值,中间变量值,退出函数前准备返回的值,返回函数到调用处后函数名字+各参数值+返回值”这些信息写日志到文件中是无论如何也发现不了问题在哪里的,包括捕获各种异常、写日志到屏幕、单步或设断点或生成core或dmp文件、……这些方法都不行!
靠冥想和顿悟帮自己查不可再现错误
假死的各种原因:
·控制循环的变量的取值范围有符号/无符号,==/<=
·控制循环的变量没变
·控制循环的变量被外部程序修改
·各种资源泄露
·死锁
·网速变慢或网络资源耗尽或网络时通时断
·权限、UAC、杀毒软件实时防护
·操作系统或软件自动升级
·以为系统时间不可逆
·以为系统时间相关变量不会溢出(GetTickCount()约49.7天就归0了!)
·……
不要企图优雅的结束(因为这是不可能办到的)
而要在烂的不能再烂的摊子上也能重整河山!