正确的read()

从一个虚拟设备里读取数据,我是用read系统调用一次读完,发现反复读取多次后,数据出现了问题。

由于是自己写的虚拟设备,所以先怀疑是kernel module写的有问题,我自己实现了虚拟设备的read方法,难道偏移量的处理有问题?于是拿出万能的printk,调试......咦,怪了,怎么dmesg里打出的消息数不对?喔,dmesg的缓冲区设小了,改个大的,10M

dmesg -s 10485760​

测完,我在把内核数据通过copy_to_user拷给用户态之前还是正常的,拷了就不正常了,这这这,我记得copy_to_user就是判断一下内存空间的有效性,本身不会乱来的呀,好,为了证明,我改成memcpy。

还是不行,似乎只要把数据拷贝一下就不对了,神了......

最后终于发现,和module的代码没关系,是我在read的时候没有对读取的数据做结尾:

read(fd, buffer, BUFFER_SIZE);

// process buffer

正确的做法是:

int res = read(fd, buffer, BUFFER_SIZE);

buffer[res] = 0;

// process buffer

唉,一个简单的代码疏漏耗费半天时间。要是有个代码高手指导指导我就好了。


相关文章

分类

3 Comments

udpwork said:

并非read的问题, 而是你没弄明白什么是C字符串. C字符串是一段以'\0'结尾的字节数组, 在没有保证是以'\0'结尾之前, 你就把字节数组当做字符串, 然后用str*字符串处理函数来处理, 不出问题只是偶然. 另外, 为了表明你要处理的是字符串, 应该是buffer[res] = '\0', 而不是等于0, 虽然两者效果相同, 但能看出你是否明白你在处理的是什么东西.

DongHao Author Profile Page said:

我当然明白c字符串是什么。原先我是用fgets一行行的读(fgets自己带'\0'),后来改为read一次读,而代码处理文件内容的逻辑没有变,所以出问题了。
难点不在于字符串后面加没加'\0',而在于:系统大了,你无法快速确定问题在哪里。
多谢提醒 :)

cokecoffe said:

有时候就是一个小问题会需要很久时间

留言:

关于文章

This page contains a single entry by DongHao published on 09 17, 2010 11:44 AM.

蜂蜜 was the previous entry in this blog.

笑话又两则 is the next entry in this blog.

Find recent content on the main index or look in the 存档 to find all content.