第三方函数没有写任何数据过去,getline返回的脏数据不是别人写进去的,是真实的从内核返回的文件数据。
我还是搞到了第三方函数的代码,大致梳理了一下它的逻辑,发现这个函数fork了一个子进程,然后waitpid。
于是问题就清楚了,子进程退出的时候,把getline读取的那个FILE的位置重置了。这是Linux系统的逻辑,比如说getline从内核读了4K的数据到自己的用户态buffer里面,然后给调用者返回了1K,那么在进程退出的时候,剩下的3K要还回给内核,于是内核把FILE的已读取位置回退了3K。然后第三方函数执行完毕返回主循环,主循环继续调用getline,那么在getline把4K的用户态buffer用完了之后,再读下一个4K的时候,其实读的是回退的3K加新的1K。于是getline就从用户态copy了旧的数据返回给调用者了。
我自己用类似的方法写了一个函数复现了这个问题。
我真是没办法了才去GDB标准库的。。。
总之,getline确实是thread safe的,因为有锁。但是这个锁保护的只是getline的并发调用,无法保护子进程退出时对buffer的操作。
【 在 slowaction 的大作中提到: 】
: 我理解,你需要先知道哪里错了,写了个什么数据过去
: 然后才能去分析这个错误为什么会导致库异常行为
: 你上去就gdb标准库,这是选了一条最难的路
--
修改:flingfish FROM 43.254.66.*
FROM 43.254.66.*