Repository navigation
SIGSEGV in file_server #9
Copy link
Copy link
Open
Labels
help wantedExtra attention is neededExtra attention is needed
Description
Based on the configuration and work around from #8 I get a SIGSEGV:
Program received signal SIGSEGV, Segmentation fault.
io_uring_get_sqe (ring=0x41b58ab3) at queue.c:323
323 return __io_uring_get_sqe(sq, io_uring_smp_load_acquire(sq->khead));
(gdb) p sq
$1 = (struct io_uring_sq *) 0x41b58ab3
(gdb) p *sq
Cannot access memory at address 0x41b58ab3
(gdb) bt
#0 io_uring_get_sqe (ring=0x41b58ab3) at queue.c:323
#1 0x0004a646 in io_service::io_uring_get_sqe_safe (this=0x41b58ab3) at ../io_service.hpp:631
#2 0x0004a2dc in io_service::close (this=0x41b58ab3, fd=6, iflags=0 '\000') at ../io_service.hpp:515
#3 0x0004124e in accept_connection(io_service&, int, int)::{lambda(int)#1}::operator() (frame_ptr=0xf4601a60) at ./file_server.cpp:119
#4 0x00045062 in std::__n4861::coroutine_handle<void>::resume (this=0xf440368c) at /opt/OSELAS.Toolchain-2020.08.0/arm-v7a-linux-gnueabihf/gcc-10.2.1-clang-10.0.1-glibc-2.32-binutils-2.35-kernel-5.8-sanitized/arm-v7a-linux-gnueabihf/include/c++/10.2.1/coroutine:126
#5 0x0004ad36 in task_promise_base<void, false>::final_suspend()::Awaiter::await_suspend(std::__n4861::coroutine_handle<void>) const (this=0xf4403b2c, caller=...) at ../task.hpp:37
#6 0x0004071e in serve (frame_ptr=0xf4403680) at ./file_server.cpp:97
#7 0x00045062 in std::__n4861::coroutine_handle<void>::resume (this=0xf420388c) at /opt/OSELAS.Toolchain-2020.08.0/arm-v7a-linux-gnueabihf/gcc-10.2.1-clang-10.0.1-glibc-2.32-binutils-2.35-kernel-5.8-sanitized/arm-v7a-linux-gnueabihf/include/c++/10.2.1/coroutine:126
#8 0x0004ad36 in task_promise_base<void, false>::final_suspend()::Awaiter::await_suspend(std::__n4861::coroutine_handle<void>) const (this=0xf4203e48, caller=...) at ../task.hpp:37
#9 0x0003f2c2 in http_send_file (frame_ptr=0xf4203880) at ./file_server.cpp:75
#10 0x00045062 in std::__n4861::coroutine_handle<void>::resume (this=0xf46064cc) at /opt/OSELAS.Toolchain-2020.08.0/arm-v7a-linux-gnueabihf/gcc-10.2.1-clang-10.0.1-glibc-2.32-binutils-2.35-kernel-5.8-sanitized/arm-v7a-linux-gnueabihf/include/c++/10.2.1/coroutine:126
#11 0x000496c6 in task_promise_base<int, true>::final_suspend()::Awaiter::await_suspend(std::__n4861::coroutine_handle<void>) const (this=0xf4606504, caller=...) at ../task.hpp:37
#12 0x0003c2ca in io_service::_ZN10io_service10await_workEP12io_uring_sqeh.actor(io_service::_ZN10io_service10await_workEP12io_uring_sqeh.frame *) (frame_ptr=0xf46064c0) at ../io_service.hpp:622
#13 0x00045062 in std::__n4861::coroutine_handle<void>::resume (this=0xf46064f0) at /opt/OSELAS.Toolchain-2020.08.0/arm-v7a-linux-gnueabihf/gcc-10.2.1-clang-10.0.1-glibc-2.32-binutils-2.35-kernel-5.8-sanitized/arm-v7a-linux-gnueabihf/include/c++/10.2.1/coroutine:126
#14 0x00051a94 in promise<int, true>::resolve<int&, void> (this=0xf46064ec, u=<error reading variable>) at ../promise.hpp:60
#15 0x0004f6f6 in io_service::run<void, false> (this=0xffd594f0, t=...) at ../io_service.hpp:663
#16 0x00042e90 in main (argc=2, argv=0xffd59754) at ./file_server.cpp:151
(gdb) up
#1 0x0004a646 in io_service::io_uring_get_sqe_safe (this=0x41b58ab3) at ../io_service.hpp:631
631 auto* sqe = io_uring_get_sqe(&ring);
(gdb)
#2 0x0004a2dc in io_service::close (this=0x41b58ab3, fd=6, iflags=0 '\000') at ../io_service.hpp:515
515 auto* sqe = io_uring_get_sqe_safe();
(gdb) p *this
Cannot access memory at address 0x41b58ab3
This looks to me that the coroutine created in https://github.com/CarterLi/liburing4cpp/blob/async/demo/file_server.cpp#L102 got destroyed before the code reaches https://github.com/CarterLi/liburing4cpp/blob/async/demo/file_server.cpp#L114.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
help wantedExtra attention is neededExtra attention is needed
Activity
MatthiasMann commentedon Nov 3, 2020
After some debugging it looks more like the address of service gets corrupted somehow.
For testing I stored all instances of this task<> in a std::vector and also added prints:
Before the try/catch block the address of service was 0xfff1bf50 and after it is 0x41b58ab3 - no idea currently what is happening.
CarterLi commentedon Nov 3, 2020
It's strange that echo_server doesn't have the similar issue, through they have the similar code.Ok they resulted in the similar error when compiling with g++-10
I have to say that they used to work -_-|| Will investigate it more tomorrow.
MatthiasMann commentedon Nov 3, 2020
I haven't actually tested echo server.
I also tried to compile using clang - but that had other issues on my end (couldn't find it's C++ header files like string).
CarterLi commentedon Nov 3, 2020
Reinstalling libc++-dev may resolve this issue
MatthiasMann commentedon Nov 3, 2020
If it would be a normal clang installation for the host itself then maybe - but in this case it's a cross platform tool chain (OSELAS-Toolchain). I'll look into what when wrong while building it another day.
codeinred commentedon Sep 22, 2021
Regarding this issue, have you tried compiling the library with g++-11? When working on a coroutine library I noticed that g++-10 had a number of small bugs in the way it handled coroutines. These bugs didn't appear in clang 10, but they were still annoying to work around.
hflsmax commentedon Sep 23, 2021
I used g++-11 and it still segfault when running echo_server. Here's the backtrace
@codeinred are you able to get them running? What compiler did you use?
CarterLi commentedon Sep 23, 2021
Seems the only working compiler is clang-9. The stack is cracked as long as mutiple coroutines run in parallel.
The crashes can be easily avoided by removing Line 24. In this case only one connection can be accepted at a time.
liburing4cpp/demo/echo_server.cpp
Line 24 in a9b422b
CarterLi commentedon Sep 23, 2021
All implementations of C++20 coroutine libraries I can find on the Internet are lazy - the coroutine body wont be executed before it being co_awaited, which means coroutines can never be run in parallel without threads.
That makes io_uring mostly useless. I dont bother to do that.
CarterLi commentedon Sep 23, 2021
I'd suggest that you'd better use stackful coroutines for now for both stablility and performance:
codeinred commentedon Sep 23, 2021
With regard to coroutine libraries being lazy: In the typical case, an executor can also start a coroutine before it's co_await'd on. So the coroutine is lazy because all the coroutines can be registered with an executor, before they're started.
As for allocations with promise objects: calling a function like
readorwriteshould just return an awaitable. These awaitables shouldn't allocate, but right now they're implemented astasks in your library, which leads to unnecessary allocation and also may result in a race condition.We can avoid this allocation entirely be changing the way value resolution occurs. Rather than a promise type having a
resolvefunction, we can write a really simple resolver like so:We can then write a non-allocating trivially destructible awaitable type that represents any
io_uringoperation. I'm still studying liburing, so this may not be entirely correct, but it's what I understand from reading your code:Whenever you
read,write, or do another async operation, it just creates and returns the above awaitable type on the stack (no allocation), which registers itself with the ring. No allocation occurs, and everyone's happy!Coincidentally, this also happens to avoid the bug I mentioned above in gcc-10. That bug only applies when awaitables created in a
co_awaitstatement have a non-trivial destructor, but becausesqe_awaitableis non-owning, it's trivially destructible.global: overall code cleanups; also apply suggestions in #9
codeinred commentedon Sep 27, 2021
Hi everyone,
Given the recent code cleanups, and the addition of sqe_awaitable, I'm not sure this bug still exists. I've attached an echo client I'm using to do the test below. When I run the echo server, I get the following output:
This comes from running the echo client, which receives the response it's supposed to:
The echo server accepts multiple successive incoming connections without issue.
Shown below is the code for the echo client, which I took from the python network programming cookbook:
Could I have some guidance on how to recreate this bug, if it still exists? I also tried running the echo server with the memory sanitizer enabled, and in valgrind, and both of those were happy with it.
hflsmax commentedon Sep 27, 2021
Thanks for the effort! @codeinred I can still reproduce the bug using g++-11 after reverting the temporary workaround introduced here 324f21c#diff-df6aad85015654783d708d610b1aec0ede8a3c8e29cf0057f3c7dd4ede9cbfcd
codeinred commentedon Sep 27, 2021
I see, thank you! This gives me a good starting point!
rzbdz commentedon Apr 5, 2022
I think maybe the problem before workaround occurs because of the lambda coroutine ?
liburing4cpp/demo/echo_server.cpp
Line 24 in a9b422b
Before the workaround, in this line, the lambda object do capture 2 variables, but soon after the lambda expires it's lifetime when it was called then suspended, the inner while loop scope exit, the object might be gone. The same thing just happends in the file_server.
FYI, This and
This.
demo: try fixing #9