Project

General

Profile

Actions

Bug #8202

closed

wApp returns nullptr inside a WServer::postAll lambda

Added by Emeric Poupon over 3 years ago. Updated about 3 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Target version:
Start date:
03/13/2021
Due date:
% Done:

100%

Estimated time:

Description

Hello,

I have this code, called from a thread outside the WIOService used by the WServer:

server.postAll([]
{
    wApp->getEventXXX().emit();
    wApp->triggerUpdate();
});

And it looks like wApp is nullptr.
Here is what I get in the core file:

(gdb) bt
#0  0x00039a50 in Wt::Signals::Impl::ProtoSignal<>::emit() const (this=0x4d4) at /usr/include/Wt/Signals/signals.hpp:216
#1  0x00033ee0 in Wt::Signal<>::emit() const (this=<optimized out>) at /usr/include/Wt/WSignal.h:758
#2  <lambda()>::<lambda()>::operator() (__closure=<optimized out>) at ./src/lms/main.cpp:131
#3  std::_Function_handler<void(), proxyScannerEventsToApplication(Scanner::IScanner&, Wt::WServer&)::<lambda()>::<lambda()> >::_M_invoke(const std::_Any_data &) (
    __functor=...) at /usr/include/c++/8/bits/std_function.h:297
#4  0xb69ac7dc in std::function<void ()>::operator()() const (this=<optimized out>) at /usr/include/c++/8/bits/std_function.h:682
#5  Wt::WebSession::notify (this=this@entry=0xac304658, event=...) at ./src/web/WebSession.C:2214
#6  0xb69af4b0 in Wt::WebSession::externalNotify (this=this@entry=0xac304658, event=...) at ./src/Wt/WEvent.h:137
#7  0xb69af5c4 in Wt::WebSession::processQueuedEvents (this=0xac304658, handler=...) at ./src/web/WebSession.h:396
#8  0xb69af850 in Wt::WebSession::Handler::~Handler (this=0xae0fb954, __in_chrg=<optimized out>) at ./src/web/WebSession.C:1053
#9  0xb6992c80 in Wt::WebController::handleApplicationEvent (this=0x12b7210, event=...) at ./src/web/WebController.C:544
#10 0xb66b85d4 in std::function<void ()>::operator()() const (this=0xae0fb9bc) at /usr/include/c++/8/bits/std_function.h:682
#11 boost::asio::asio_handler_invoke<std::function<void ()> >(std::function<void ()>&, ...) (function=...) at /usr/include/boost/asio/handler_invoke_hook.hpp:69
#12 boost_asio_handler_invoke_helpers::invoke<std::function<void ()>, std::function<void ()> >(std::function<void ()>&, std::function<void ()>&) (context=..., function=...)
    at /usr/include/boost/asio/detail/handler_invoke_helpers.hpp:37
#13 boost::asio::detail::handler_work<std::function<void ()>, boost::asio::system_executor>::complete<std::function<void ()> >(std::function<void ()>&, std::function<void ()>&) (this=<synthetic pointer>, handler=..., function=...) at /usr/include/boost/asio/detail/handler_work.hpp:82
#14 boost::asio::detail::completion_handler<std::function<void ()> >::do_complete(void*, boost::asio::detail::scheduler_operation*, boost::system::error_code const&, unsigned int) (owner=owner@entry=0x14601b0, base=0xae907860) at /usr/include/boost/asio/detail/completion_handler.hpp:70
#15 0xb66ba8c8 in boost::asio::detail::scheduler_operation::complete (bytes_transferred=0, ec=..., owner=0x14601b0, this=<optimized out>)
    at /usr/include/boost/asio/detail/scheduler_operation.hpp:40
#16 boost::asio::detail::strand_service::do_complete (owner=owner@entry=0x14601b0, base=base@entry=0x1460ef8, ec=...)
    at /usr/include/boost/asio/detail/impl/strand_service.ipp:168
#17 0xb66b4ed8 in boost::asio::detail::scheduler_operation::complete (bytes_transferred=<optimized out>, ec=..., owner=0x14601b0, this=0x1460ef8)
    at /usr/include/boost/asio/detail/scheduler_operation.hpp:40
#18 boost::asio::detail::scheduler::do_run_one (ec=..., this_thread=..., lock=..., this=0x14601b0) at /usr/include/boost/asio/detail/impl/scheduler.ipp:401
#19 boost::asio::detail::scheduler::run (ec=..., this=0x14601b0) at /usr/include/boost/asio/detail/impl/scheduler.ipp:154
#20 boost::asio::io_context::run (this=<optimized out>) at /usr/include/boost/asio/impl/io_context.ipp:62
#21 Wt::WIOService::run (this=<optimized out>) at ./src/Wt/WIOService.C:180
#22 0xb631a9b0 in ?? () from /usr/lib/arm-linux-gnueabihf/libstdc++.so.6
#23 0xb6e0f494 in start_thread (arg=0xae0fc0e0) at pthread_create.c:486
#24 0xb6157578 in ?? () at ../sysdeps/unix/sysv/linux/arm/clone.S:73 from /lib/arm-linux-gnueabihf/libc.so.6
(gdb)  p (*Wt::threadHandler_->sessionPtr_)->app_
$11 = (Wt::WApplication *) 0x0

(Source is here if you want to see more: https://github.com/epoupon/lms/blob/v3.24.0/src/lms/main.cpp#L131)
What do you think?

Actions #1

Updated by Emeric Poupon over 3 years ago

Wt 4.2.0, crashing on raspbian

Actions #2

Updated by Korneel Dumon over 3 years ago

  • Status changed from New to InProgress
  • Assignee set to Korneel Dumon

This seems to happen when you close the page before it is finished loading. I can reproduce it by throttling the browser so I am quick enough to close it. Can you confirm this?

I think it has something to do with Wt's bootstrap process. If you close the page before the bootstrap request is finished, then we created a WebSession, but not yet a WApplication.
My suspicion is confirmed by the fact that the problem is gone when I enable progressive bootstrap (which renders the application on the first request).

Even if there is no wApp, the session is still cleaned up after a while. So if you just add a null-check, you should be good. I will see if I can also add it somewhere in Wt to prevent this from happening.

Actions #3

Updated by Emeric Poupon over 3 years ago

Korneel Dumon wrote in #note-2:

This seems to happen when you close the page before it is finished loading. I can reproduce it by throttling the browser so I am quick enough to close it. Can you confirm this?

I think it has something to do with Wt's bootstrap process. If you close the page before the bootstrap request is finished, then we created a WebSession, but not yet a WApplication.
My suspicion is confirmed by the fact that the problem is gone when I enable progressive bootstrap (which renders the application on the first request).

Even if there is no wApp, the session is still cleaned up after a while. So if you just add a null-check, you should be good. I will see if I can also add it somewhere in Wt to prevent this from happening.

Hello!

Unfortunately, I don't manage to reproduce this issue :(
But a user reported he gets this 100%, not mentioning the closing step (see https://github.com/epoupon/lms/issues/126 for for more details)
Indeed I don't use the progressive bootstrap feature.

Actions #4

Updated by Korneel Dumon over 3 years ago

Perhaps your user always has unfortunate timing. Between the first and second request there is always a small interval where wApp is null. If you call postAll() during this time, it will crash. The conclusion is the same, you can safely ignore these incomplete applications.
You can stretch the interval by throttling the browser, maybe you can reproduce it in this way.

Actions #5

Updated by Korneel Dumon over 3 years ago

  • Status changed from InProgress to Implemented @Emweb
Actions #6

Updated by Roel Standaert over 3 years ago

  • Status changed from Implemented @Emweb to Resolved
  • Target version set to 4.5.1
Actions #7

Updated by Roel Standaert over 3 years ago

  • % Done changed from 0 to 100
Actions #8

Updated by Roel Standaert about 3 years ago

  • Status changed from Resolved to Closed
Actions

Also available in: Atom PDF