Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested boost::asio::spawn and Valgrind #1454

Closed
OleStauning opened this issue Mar 25, 2024 · 1 comment
Closed

Nested boost::asio::spawn and Valgrind #1454

OleStauning opened this issue Mar 25, 2024 · 1 comment

Comments

@OleStauning
Copy link

OleStauning commented Mar 25, 2024

I am trying to debug a larger program using boost asio that runs for a while and then crashes is various ways. I have tried to locate the bug using Valgrind and have reproduced a minimal example with a nested boost::asio::spawn where Valgrind says there is an invalid read.

The example is:

#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>

int main()
{
	boost::asio::io_context io_context;
	
	boost::asio::spawn(io_context, 
		[&](boost::asio::yield_context yield) 
		{
			std::cout<<"Spawn #1"<<std::endl;
			
			boost::asio::spawn(yield, // Have also tried with io_context
				[](boost::asio::yield_context yield2) 
				{
					std::cout<<"Spawn #2"<<std::endl;
				});
		});
	
	io_context.run();
	
	return 0;
}

Running the example with valgrind gives:

$ valgrind ./nestspawn 
==377032== Memcheck, a memory error detector
==377032== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==377032== Using Valgrind-3.23.0.GIT and LibVEX; rerun with -h for copyright info
==377032== Command: ./nestspawn
==377032== 
==377032== Warning: client switching stacks?  SP change: 0x1ffefff948 --> 0x4e0d6f8
==377032==          to suppress, use: --max-stackframe=137340330576 or greater
==377032== Warning: client switching stacks?  SP change: 0x4e0d408 --> 0x1ffefff948
==377032==          to suppress, use: --max-stackframe=137340331328 or greater
==377032== Warning: client switching stacks?  SP change: 0x1ffefff7a8 --> 0x4e0d408
==377032==          to suppress, use: --max-stackframe=137340330912 or greater
==377032==          further instances of this message will not be shown.
Spawn #1
==377032== Invalid read of size 8
==377032==    at 0x1129B6: void boost::coroutines::detail::trampoline_pull<boost::coroutines::detail::pull_coroutine_object<boost::coroutines::push_coroutine<void>, void, boost::asio::detail::spawned_coroutine_thread::entry_point<boost::asio::detail::old_spawn_entry_point<boost::asio::any_io_executor, main::{lambda(boost::asio::basic_yield_context<boost::asio::any_io_executor>)#1}::operator()(boost::asio::basic_yield_context<boost::asio::any_io_executor>) const::{lambda(boost::asio::basic_yield_context<boost::asio::any_io_executor>)#1}, void (*)()> >, boost::coroutines::basic_standard_stack_allocator<boost::coroutines::stack_traits> > >(boost::context::detail::transfer_t) (trampoline_pull.hpp:32)
==377032==    by 0x4CFC1F6: make_fcontext (in /usr/local/lib/libboost_context.so.1.85.0)
==377032==  Address 0x4e0d120 is 63,760 bytes inside a block of size 65,536 alloc'd
==377032==    at 0x484880F: malloc (vg_replace_malloc.c:446)
==377032==    by 0x124D93: boost::coroutines::basic_standard_stack_allocator<boost::coroutines::stack_traits>::allocate(boost::coroutines::stack_context&, unsigned long) (standard_stack_allocator.hpp:52)
==377032==    by 0x112B0F: boost::coroutines::pull_coroutine<void>::pull_coroutine<boost::asio::detail::spawned_coroutine_thread::entry_point<boost::asio::detail::old_spawn_entry_point<boost::asio::strand<boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul> >, main::{lambda(boost::asio::basic_yield_context<boost::asio::any_io_executor>)#1}, void (*)()> > >(boost::asio::detail::spawned_coroutine_thread::entry_point<boost::asio::detail::old_spawn_entry_point<boost::asio::strand<boost::asio::io_context::basic_executor_type<std::allocator<void>, 0ul> >, main::{lambda(boost::asio::basic_yield_context<boost::asio::any_io_executor>)#1}, void (*)()> >&&, boost::coroutines::attributes const&) (asymmetric_coroutine.hpp:1474)
.... continues 

As far as I know it is legal to use nested spawn. So what is wrong in the code?

Best regards

@OleStauning
Copy link
Author

Seems that boost needed to be configured with valgrind=on and BOOST_USE_VALGRIND needed to be defined in the code.

Now the example runs with valgrind without any errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant