I stumbled upon a bug almost immediately after using it casually. If ACE_Dev_Poll_Reactor is utilized, the destructor of the Reactor first calls close on the ACE_Dev_Poll_Reactor before deleting it, and then the destructor of ACE_Dev_Poll_Reactor also closes itself. This means that ACE_Dev_Poll_Reactor must be closed twice, which is unavoidable. However, when the token_ lock is used in the close function of ACE_Dev_Poll_Reactor, it relies on notify_handler_, which has already been released during the first close. Consequently, the second close inevitably leads to a segmentation fault.What's maddening is that this error seems impossible to avoid no matter what. How could such a low-level mistake exist? Can this library really be considered usable?
Thread 1 "ftpd_test" received signal SIGSEGV, Segmentation fault.
ACE_Dev_Poll_Reactor::notify (this=0x5555555c8e70, eh=0x0, mask=4, timeout=0x7fffffffdaf0) at /home/liwenhui/dev/ACE_wrappers/ace/Dev_Poll_Reactor.cpp:2062
2062 n = this->notify_handler_->notify (eh, mask, timeout);
(gdb) bt
#0 ACE_Dev_Poll_Reactor::notify (this=0x5555555c8e70, eh=0x0, mask=4, timeout=0x7fffffffdaf0) at /home/liwenhui/dev/ACE_wrappers/ace/Dev_Poll_Reactor.cpp:2062
#1 0x00007ffff7e9bb74 in ACE_Reactor_Token_T<ACE_Token>::sleep_hook (this=<optimized out>) at /home/liwenhui/dev/ACE_wrappers/ace/Reactor_Token_T.cpp:65
#2 0x00007ffff7f33b02 in ACE_Token::shared_acquire (this=0x5555555c8e90, sleep_hook_func=0x0, arg=0x0, timeout=0x0, op_type=<optimized out>) at /home/liwenhui/dev/ACE_wrappers/ace/Token.cpp:248
#3 0x00007ffff7ebef8f in ACE_Guard<ACE_Reactor_Token_T<ACE_Token> >::acquire (this=<synthetic pointer>) at /home/liwenhui/dev/ACE_wrappers/ace/Guard_T.inl:11
#4 ACE_Guard<ACE_Reactor_Token_T<ACE_Token> >::ACE_Guard (l=..., this=<synthetic pointer>) at /home/liwenhui/dev/ACE_wrappers/ace/Guard_T.inl:37
#5 ACE_Dev_Poll_Reactor::close (this=0x5555555c8e70) at /home/liwenhui/dev/ACE_wrappers/ace/Dev_Poll_Reactor.cpp:827
#6 0x00007ffff7ebf185 in ACE_Dev_Poll_Reactor::~ACE_Dev_Poll_Reactor (this=0x5555555c8e70, __in_chrg=<optimized out>) at /home/liwenhui/dev/ACE_wrappers/ace/Dev_Poll_Reactor.cpp:666
#7 0x00007ffff7ebf21d in ACE_Dev_Poll_Reactor::~ACE_Dev_Poll_Reactor (this=0x5555555c8e70, __in_chrg=<optimized out>) at /home/liwenhui/dev/ACE_wrappers/ace/Dev_Poll_Reactor.cpp:667
#8 0x00007ffff7f0e3f2 in ACE_Reactor::~ACE_Reactor (this=0x5555555d7480, __in_chrg=<optimized out>) at /home/liwenhui/dev/ACE_wrappers/ace/Reactor.cpp:87
#9 0x00007ffff7f0e40d in ACE_Reactor::~ACE_Reactor (this=0x5555555d7480, __in_chrg=<optimized out>) at /home/liwenhui/dev/ACE_wrappers/ace/Reactor.cpp:88
#10 0x00007ffff7faf270 in std::default_delete<ACE_Reactor>::operator() (this=0x7fffffffddc0, __ptr=0x5555555d7480) at /usr/include/c++/11/bits/unique_ptr.h:85
#11 0x00007ffff7faf4ad in std::__uniq_ptr_impl<ACE_Reactor, std::default_delete<ACE_Reactor> >::reset (this=0x7fffffffddc0, __p=0x0) at /usr/include/c++/11/bits/unique_ptr.h:182
#12 0x00007ffff7faf003 in std::unique_ptr<ACE_Reactor, std::default_delete<ACE_Reactor> >::reset (this=0x7fffffffddc0, __p=0x0) at /usr/include/c++/11/bits/unique_ptr.h:456
#13 0x00007ffff7fae5a9 in lwh::Ftp_Server::~Ftp_Server (this=0x7fffffffddc0, __in_chrg=<optimized out>) at /home/liwenhui/dev/ftpd_remote/src/ftp_server.cpp:45
#14 0x00005555555628d5 in FtpdTest_Basic_Test::TestBody (this=0x5555555c8d50) at /home/liwenhui/dev/ftpd_remote/src/test/command_test.cpp:53
#15 0x000055555559532f in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) ()
#16 0x00005555555890c6 in testing::Test::Run() ()
#17 0x0000555555589245 in testing::TestInfo::Run() ()
#18 0x00005555555897f9 in testing::TestSuite::Run() ()
#19 0x0000555555589eff in testing::internal::UnitTestImpl::RunAllTests() ()
#20 0x00005555555958f7 in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) ()
#21 0x000055555558930c in testing::UnitTest::Run() ()
#22 0x0000555555563e8c in RUN_ALL_TESTS () at /usr/include/gtest/gtest.h:2490
#23 0x0000555555563dfc in main (argc=1, argv=0x7fffffffe268) at /home/liwenhui/dev/ftpd_remote/src/test/test_driver.cpp:7
Version
7.0
Host machine and operating system
linux
I stumbled upon a bug almost immediately after using it casually. If
ACE_Dev_Poll_Reactor
is utilized, the destructor of the Reactor first callsclose
on theACE_Dev_Poll_Reactor
before deleting it, and then the destructor ofACE_Dev_Poll_Reactor
alsocloses
itself. This means thatACE_Dev_Poll_Reactor
must be closed twice, which is unavoidable. However, when thetoken_
lock is used in theclose
function ofACE_Dev_Poll_Reactor
, it relies onnotify_handler_
, which has already been released during the firstclose
. Consequently, the secondclose
inevitably leads to a segmentation fault.What's maddening is that this error seems impossible to avoid no matter what. How could such a low-level mistake exist? Can this library really be considered usable?