程序调试随笔

来源:互联网 发布:java多线程写入数据库 编辑:程序博客网 时间:2024/06/05 17:28
技巧
__FILE__、__FUNCTION__、__LINE__
使用宏代替printf
输出乱码导致屏幕错乱
执行reset命令,还不行就只有重新login了




输出缓冲区问题
《UNIX环境高级编程》说:
标准出错绝不会是全缓冲的
当且仅当标准输出并不涉及交互作用设备时才是全缓存的
用fprintf(stderr…)
一定用printf的话
不重定向到文件
及时换行
fflush(stdout)强制刷新缓冲区
setbuf/setvbuf重设缓冲方式
一般不要用write(1,…),否则容易混乱


输出缓冲区问题
fflush(fp)
setbuf、setvbuf重设缓冲方式
用非缓冲API(write等)
一般不要混合使用缓冲型API与非缓冲型API,否则容易混乱


多执行流安全问题
最好每个执行流(线程/进程)写一个文件,不要重合
否则,争取每次LOG只调用一次write()
先snprintf整句LOG信息,再write一次


内存LOG
适用情况
运营中的系统
负载高、错误难以重现,直接LOG性能太低
原理
LOG时不写磁盘,而是写内存
当发现错误出现的时候才把LOG从内存写入磁盘


应对普通的逻辑错误(进程没有死)
平时把LOG写到内存中
一旦发现错误重现,则立刻把内存中的信息LOG到文件中


应对CoreDump
需要使用共享内存
平时
收到请求包时, LOG整个请求包的内容
处理过程中,可以LOG一些处理过程
发出回应包,准备收下个请求包时,清除内存LOG
启动时
如果共享内存里面有内容,则把该内容LOG到文件中
使用LOG到文件中的请求包进行分析
多数情况下,重发该包,就能直接跟踪出bug




strace/ltrace
分清系统调用和库函数
系统调用:Linux内核提供的API
库函数:运行时库提供的函数,也可以是系统调用的包裹函数(Wrapper)
功能
Strace:显示程序调用的系统调用
Ltrace: 显示程序调用的动态库的库函数
用途
Debug、性能分析、学习现有程序
重要参数
-p pid:attach现有进程
-e abc,xyz…:只跟踪指定的系统调用/库函数
-T –tt显示单个系统调用的开始时间、执行时间


GDB
跟踪变量写乱的一般步骤
Gdb attach后
Break设定断点(在该断点后,变量应该不会被改写)
Continue
到达上述断点后
Watch设定监控断点
Continue
程序修改该变量时,会中断回到gdb
Backtrace
打印各层函数栈的内容
如果不是预想中要修改该变量的代码,则找到该BUG了
大部分BUG可以通过上述步骤找到
如果找不到,则可能说明
该变量在共享内存,被另外一个执行流修改了
原创粉丝点击