Linux下C开发排错

编译错误、运行core、运行异常

除第六点目前为遇到,其他遇问题已经遇到过。部分用于线程程序出现问题排查。经常排错时候直接看日志会忽略硬盘满,目前遇到三次,基本是程序内输出流过多或日志打印过多。

1日志记录

程序调试等用户日志

系统日志 /var/log/messages等

 

2 程序僵死

锁冲突 或 阻塞系统函数阻塞 或 硬盘空间满

通过ps -xH|grep 程序名

程序锁僵死,目前为使用其他工具查问题,直接人工审查代码发现的问题。

3 查看磁盘空间沾满,空间不足

df -h

du --max-depth=1 -h

可能存在某个文件rm删除,但是还被其他程序写入,即实际未删除

对端请求被拒绝,

程序w清空写文件备份等失败-空文件-程序流程异常

lsof|grep deleted #查看删除文件仍被执行使用

样例输出流打印,程序nohup.out满删除,程序未重启

解决方法 -还在写入的程序重启

守护进程启用nohup proname & >/dev/null

4 CPU高统计

进程PID获取pidof 程序名 或者 ps -ef|grep 程序名

top -Hp `pidof 程序`

#CPU高 假如是12759线程

strace -T -r -c -p 12759

strace -cp 12759

#运行一段时间后 CTRL+C得出统计结果

https://blog.csdn.net/Msy3TU4dFuUZ4/article/details/78930032

阻塞的read

top -H -p 12759 #查找进程pid找到占用CPU最大的线程

pstack -p 12759 #定位进程pid占用CPU最大的线程入口tid-12760

--无休眠循环基本可以判断占用CPU高的原因

trace -p 12760#没找到命令

ltrace 要程序退出?https://www.cnblogs.com/machangwei-8/p/10388938.html

#得出哪个系统调用占用时间多,eg select 检测字符集含非法值

https://www.cnblogs.com/Jimmy104/p/5254710.html

若是select 对应休眠参数设置适当休眠时间。

通过上面的显示我们发现Cpu(s)表示的是 所有用户进程占用整个cpu的平均值,由于每个核心占用的百分比不同,所以按平均值来算比较有参考意义。而%CPU显示的是进程占用一个核的百分比,而不是整个cpu(12核)的百分比,有时候可能大于100,那是因为该进程启用了多线程占用了多个核心,所以有时候我们看该值得时候会超过100%,但不会超过总核数*100。

5 PRO*C编译 

单线程thread=no 和多线程 thread=yes不一致报错。

6 Inode耗光 ,空间不足-该点目前未涉及暂存详细来自链接

知识点:https://www.cnblogs.com/itech/archive/2012/05/15/2502284.html

http://zyan.cc/post/295/

关键字:扇区、文件inode

df -h 磁盘空间正常。

lsof | grep deleted 正常

手工echo abc > test.txt失败,报没有磁盘空间

df -i #查看是否用光inode用光。

ls -i example.txt # 查看对应文件的inode

stat example.txt #查看文件inode信息

 查找原因:

  /data/cache目录中存在数量非常多的小字节缓存文件,占用的Block不多,但是占用了大量的inode。

 解决方案一:

  1、删除/data/cache目录中的部分文件,释放出/data分区的一部分inode。

  2、用软连接将空闲分区/opt中的newcache目录连接到/data/cache,使用/opt分区的inode来缓解/data分区inode不足的问题:

  ln -s /opt/newcache /data/cache

  3、更换服务器,用高配置的服务器替换低配置的服务器。很多时候用钱去解决问题比用技术更有效

解决方案二:https://blog.51cto.com/aklaus/1786402

 关于Inode一个应用的案例就是创建文件的时候发现没有足够的空间,通过df查看呢发现实际上Used只有20%,这里也是为什么du和df查看同样一个磁盘的时候发现大小不一致(自己可以试一下肯定不一致)

首先inode耗尽差生肯定是inode表没有空闲了,怎么解决???

find ./ -name "*.log*" |xargs -L rm可以删除,如果小文件太多可能会报错arglist too long

find ./ -name "*.log*" -exec rm -rf {} \;也可以删除,都是讲删除的文件一个一个做为参数传递

还有就是如果想不格式化硬盘(mkfs)可以删掉一部分之后重新指定连接到别的文件系统

ln -s /newcache /opt/newcache 这样访问就是使用新的文件系统的i节点

如果涉及前期考虑到硬盘存放的数据的大小,可以考虑以下两点: 如果有很多个小文件,在创建硬盘的时候可以调整Block小一点。 如果文件特别大,比如视频之类的,可以调整Block大一些。

 

如何增加Inode的数量只能umount文件系统,然后重新mkfs mkfs ext3 /dev/sda1 [-N number-of-inodes ]直接指定需要的Inode数目 或者mkfs ext3 /dev/sda1 [-i bytes-per-inode] inode数量如何计算:一般是硬盘大小/Block(即一个扇区)

 

7密码即将过期

8程序core

ip:428ed5 在/var/log/messages里面的ip 可定位位置

addr2line -e 程序 428ed5

或者

gdb 程序名 core.1234

>bt

9程序缺少动态文件

编译时发现缺少

ldd 程序

10.局部变作为流程控制未初始化,输入流参数未重新初始化作为流程控制

程序流程瞬间退出

程序失控死循环https://blog.csdn.net/u014646950/article/details/100144060

11.段错误

char*使用范围超限,strcmp涉及空指针由问题 ,除零错误

sizeof错误使用

sizeof(指针) 32bit四字节 64bit 八字节

sizeof(单结构体)  结构体长度包括对齐占位

sizeof(一维数组名)==整个数组长度

sizeof(a)/sizeof(a[0])  ==数组内单元个数

12.内存泄漏

线程创建失败等malloc 资源回收处理。

普通编译查

-lmcheck

valfrind

 

多线程 cancle 内存泄露 pthread_cleanup_push

 

gcc -lmcheck ./a.out --重复释放

编译

gcc -g c.c //可查看详细

valgrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes -v ./a.out

valgrind --tool=memcheck --leak-check=yes --show-reachable=yes --trace-children=yes -v ./a.out

 

valgrind --tool=massif ./a.out

图表:

ms_print massif.out.12345

http://valgrind.org/docs/manual/ms-manual.html

--可以检查没有free的 包括strdup没有free

in use at exit:退出时还有字节数 没有释放块数

total heap usage: 分配次数allocs 释放次数frees 分配字节大小【可侦测包括strdup ,gethostbyname_r】

LEAK SUMMARY

still reachable:

1 errors in context 1 of 1

invalid write of size ;违法写(eg.空间释放,野指针再次赋值)

Conditional jump or move depends on uninitialised value 值没有初始化

Use of uninitialised value of size 8

 

-D_REENTRANT检查可重入

 

不可重入函数 静态变量 全局变量 malloc/free 标准IO函数

线程安全 (no)静态变量 全局变量

异步信号安全

http://www.gnu.org/software/libc/manual/html_node/POSIX-Safety-Concepts.html#POSIX-Safety-Concepts

MT, stands for Multi Thread多线程-非原子性

AS, stands for Asynchronous Signal异步信号

AC, stands for Asynchronous Cancellation异步取消

The POSIX standard defines only three functions to be AC-Safe, 

AC-NOTsafe :pthread_cancel, pthread_setcancelstate, and pthread_setcanceltype

 

Definitely lost 申请的空间游离 泄露

still reachable 指针退出前未释放

Indirectly lost 申请的空间游离使得其他间接游离 泄漏

 

http://valgrind.org/docs/manual/mc-manual.html#mc-manual.leaks

 

 

 

使用未初始化的内存 (Use of uninitialised memory)

使用已经释放了的内存 (Reading/writing memory after it has been free’d)

使用超过 malloc分配的内存空间(Reading/writing off the end of malloc’d blocks)

对堆栈的非法访问 (Reading/writing inappropriate areas on the stack)

申请的空间是否有释放 (Memory leaks – where pointers to malloc’d blocks are lost forever)

malloc/free/new/delete申请和释放内存的匹配(Mismatched use of malloc/new/new [] vs free/delete/delete [])

src和dst的重叠(Overlapping src and dst pointers in memcpy() and related functions)

l  Callgrind

Callgrind收集程序运行时的一些数据,函数调用关系等信息,还可以有选择地进行cache模拟。在运行结束时,它会把分析数据写入一个文件。callgrind_annotate可以把这个文件的内容转化成可读的形式。

l  Cachegrind

它模拟 CPU中的一级缓存I1,D1和L2二级缓存,能够精确地指出程序中 cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。这对优化程序有很大的帮助。

l  Helgrind

它主要用来检查多线程程序中出现的竞争问题。Helgrind寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发掘的错误。Helgrind实现了名为” Eraser” 的竞争检测算法,并做了进一步改进,减少了报告错误的次数。

l  Massif

堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。

Massif能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值