【发布时间】:2015-04-27 07:48:30
【问题描述】:
我有一个使用 linux aio_write 和 aio_read 的测试实用程序。 这个测试实用程序包装了我的静态库并对其进行测试。这个库是多线程的黑盒。
到目前为止,它运行良好。但是现在我们对这个黑盒做了很大的改变,这会导致测试实用程序在提交第一个 IO 时立即失败。 此 IO 返回 errno 22 == EINVAL。
根据 aio_write 手册页,如果以下字段之一无效,则会发出此错误 --> aio_offset、aio_reqprio、aio_nbytes。 我在 gdb 中运行它并测试它们的值,只要与 struct aiocb * 输入参数中的所有其他值一样。 我的结论是输入的参数都是有效的。
我怀疑线程在黑盒内的工作方式发生了一些变化。这就是我怀疑导致此问题的原因(我找不到任何其他解释)。
我真正想了解的是:哪些场景会导致 aio_write() 返回 EINVAL 错误码???
澄清一下,当我将黑盒替换为旧版本时,使用相同的测试实用程序可以正常工作....(我还在这里测试了输入参数,因为它们与错误版本的输入参数匹配)。
【问题讨论】:
-
尝试在
strace下运行你的程序。它跟踪所有系统调用,因此有助于了解哪里出了问题。 -
请将您的解决方案作为答案发布并接受它
-
我们能够隔离并修复问题。但是……我们不明白原因。问题是添加了一个静态线程本地数组。我们的黑盒使用这种方法,在几个地方定义了线程局部变量。我通过减小一个尺寸并将其添加到新变量来修复它。例如:静态_thread new old_[1024];新代码应该是:static __thread new old_[512]; // 如果 old 是大小为 1024 的数组,我得到错误 static __thread new new_[512];这种行为我们无法解释。有人可以澄清一下吗?
-
我的伙伴找到并解释:sourceware.org/bugzilla/show_bug.cgi?id=11787 似乎 aio_write 创建了一个堆栈大小较小的线程并从中减少了 TLS 大小。所以在我们的例子中,TLS 大小很大,因此 aio_write 线程创建失败。在这种情况下,返回 EINVAL 值。
-
你有问题,你有答案,你甚至有你的结论,你不需要我们!!! 您甚至没有发布任何代码行。您认为我们将如何帮助您?
标签: c++ linux system-calls aio aio-write