设为首页 收藏本站
查看: 336|回复: 0

[经验分享] linux内核bug调试指南(一)

[复制链接]

尚未签到

发表于 2016-3-5 08:14:44 | 显示全部楼层 |阅读模式
1. do_sync_write/do_sync_read读写错误,返回值ret=-22;
通过查对应内核源代码中errno-bash.h,可以知道-22表示Invalid argument
函数调用的形式如下:
#define WRITE_STRIPE_SIZE (128*1024)
loff_t pos;
mm_segment_t oldfs;
int offset;
offset = 17000;
pos = offset * WRITE_STRIPE_SIZE;
oldfs = get_fs();
set_fs(get_ds());
ret = do_sync_write(filp, buf, count, &pos);
set_fs(oldfs);
if(ret != count)
eprintk("ret = %d, count = %d, pos = %lld/n”, ret, count, pos);
结果写出错,ret = -22pos打印出来是一个负数。
调试过程:
计算offset * WRITE_STRIPE_SIZE = 2228224000
loff_t在内核态下就是long long类型的,长度为64bit,显然2228224000没有超过loff_t的范围,但是为什么赋值之后pos就是一个负数呢?出现负数的情况一般是数值溢出了。
加入下面语句
unsigned int temp;
temp = 17000 * WRITE_STRIPE_SIZE;
然后打印出来发现temp的值就是2228224000。然后再
pos = temp;
打印出来pos的值就是2228224000
可以确定是赋值的时候导致的数值溢出了!
所以采用强制类型转换
pos = (loff_t)offset * WRITE_STRIPE_SIZE;
或者#define WRITE_STRIPE_SIZE (128ll*1024)
这样就不会溢出了。
本来就是一个很小的细节问题,只要平时注意一点就不会出现这样的bug。所以细节很重要的,编程的时候注重风格规范,否则像这样的不起眼的bug会让人困扰好几天,这也算是一种经验积累的过程。
附录:常见错误信息(errno-bash.h
#define EPERM 1 /* Operation not permitted */
#define ENOENT 2 /* No such file or directory */
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted system call */
#define EIO 5 /* I/O error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Argument list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file number */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Try again */
#define ENOMEM 12 /* Out of memory */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
#define ENOTBLK 15 /* Block device required */
#define EBUSY 16 /* Device or resource busy */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Cross-device link */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* File table overflow */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Not a typewriter */
#define ETXTBSY 26 /* Text file busy */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Illegal seek */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Math argument out of domain of func */
#define ERANGE 34 /* Math result not representable */
2. 死锁问题
iscsitarget的代码运行时出现如下问题:
iscsi_trgt: cmnd_abort(1148) 5000000 1 0 42 3584 0 0
iscsi_trgt: Abort Task (01) issued on tid:1 lun:0 by sid:281475265921536 (Unknown Task)
ietd: Can't get session param 1 4
iscsi_trgt: ioctl(282) interrupted -4 -1066374899
这个问题是由程序中加的互斥锁引起多线程访问资源导致的死锁产生的。
检查程序中加锁的地方,逻辑上判断会不会出现死锁的地方加以修改。
3. Unable to handle kernel paging request
问题如下:
Unable to handle kernel paging request at ffffc20000c03c00 RIP:
[<ffffffff882ca7f7>] :iscsi_trgt:do_write+0x10e/0x4cf
PGD 37c00067 PUD 37c01067 PMD 35492067 PTE 0
Oops: 0002 [1] SMP
……
原因一:内存拷贝的错误,一般是memcpy(dst_buf, src_buf, count)det_buf或者src_buf地址出现错误。
objdump反汇编目标文件可以查看出错的位置
objdump –S xxx.o > debug_file
定位错误:根据“do_write+0x10e/0x4cf”可以定位出错的位置,在反汇编出来的debug_file里面先找到eraid10_write的函数入口地址0xeb1,然后0x10e是出错位置的相对偏移,则出错的地址为0xeb1+0x10e=0xfbf,找到对应位置的汇编代码如下:
repz movsb %ds:(%rsi),%es:(%rdi)
这句汇编指令就是表示memcpy这个函数的功能
然后根据这个错误再查看代码,分析是由dst_buf还是src_buf引起的,然后再做具体处理。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-186481-1-1.html 上篇帖子: linux系统上android的USB调试 下篇帖子: linux创建子进程--fork()方法
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表