Linux下的C语言编程,glibc版本是glibc_2.31-13+deb11u5.debian
程序逻辑大概是这样的,从一个文件A里用getline()逐行读取,然后对每行进行字符串解析并且做相应的业务逻辑。问题是每次读到一个特定的行,getline返回的数据就会乱掉。用GDB调试之后,发现是getline把当前行的一部分,和之前已经读过的某一行拼在一起返回了。getline()是buffered io,它自己维护一个用户态buffer,先把数据从内核读到自己的用户态buffer,再把buffer里的数据copy到一块malloc出来的内存里返回给调用者。这个用户态buffer满了之后,getline()函数是要再重新读数据填buffer,并且更新相应的指针。但是GDB跟踪发现在出问题的这一行,读到buffer末尾还没找到一个\n,getline()执行重新读数据填buffer的操作,但是执行完毕的结果是指针回到了buffer头,但是buffer里的数据还是旧的。于是之前读过的某一行就这样被拼到了这一行的后面。
关掉业务逻辑,发现简单的getline逐行读取没有这个问题,由此可以断定是某业务代码破坏了getline的执行逻辑。经过缩小范围,发现是调用的某个第三方函数引起的问题。这个函数我没有源码,从注释上看这个函数的功能是dump某些数据到另外一个文件B里面。我怀疑这个函数在dump的过程中做了某种多进程/多线程的操作,或者对文件A的内核buffer产生了某种影响。
现在问题是,有没有大神对buffered io比较熟悉的,能指个方向,到底这个第三方函数可能干了什么事情,才会导致getline()出现上面所说的逻辑错误。
多谢多谢!
--
FROM 43.254.66.*