FollowMyVote/StakeWeightedVoting

App crash when vote is processed

Closed this issue · 0 comments

In certain circumstances, the app will crash when a vote is processed by the server.

Steps to reproduce:

  • Open a contest in the voting app (contest detail page, which shows the results)
  • Cast a vote on the contest in the app, but do not yet approve the transaction in the wallet
  • Leave the contest detail page, then re-open it
  • Approve the vote transaction in the wallet
  • When the server processes the vote, the voting app will crash

Backtrace:

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   org.qt-project.QtCore           0x0000000110dcb543 QObject::QObject(QObject*) + 179
1   org.qt-project.QtCharts         0x000000011124d928 QtCharts::QBarSet::QBarSet(QString, QObject*) + 24
2   VotingApp                       0x000000010fab2a49 swv::ContestResultsApi::updateBarSeries(capnp::List<Backend::ContestResults::TalliedOpinion, (capnp::Kind)3>::Reader) + 2201
3   VotingApp                       0x000000010fab45fb swv::ContestResultsApi::ResultsNotifier::notify(capnp::CallContext<Notifier<capnp::List<Backend::ContestResults::TalliedOpinion, (capnp::Kind)3> >::NotifyParams, Notifier<capnp::List<Backend::ContestResults::TalliedOpinion, (capnp::Kind)3> >::NotifyResults>) + 171
4   VotingApp                       0x000000010fabeac5 Notifier<capnp::List<Backend::ContestResults::TalliedOpinion, (capnp::Kind)3> >::Server::dispatchCallInternal(unsigned short, capnp::CallContext<capnp::AnyPointer, capnp::AnyPointer>) + 133
5   VotingApp                       0x000000010fabc7ab Notifier<capnp::List<Backend::ContestResults::TalliedOpinion, (capnp::Kind)3> >::Server::dispatchCall(unsigned long long, unsigned short, capnp::CallContext<capnp::AnyPointer, capnp::AnyPointer>) + 123
6   StubChainAdaptor                0x0000000111ea906c kj::_::TransformPromiseNode<kj::Promise<void>, kj::_::Void, capnp::LocalClient::call(unsigned long long, unsigned short, kj::Own<capnp::CallContextHook>&&)::'lambda'(), kj::_::PropagateException>::getImpl(kj::_::ExceptionOrValue&) + 506
7   StubChainAdaptor                0x0000000111eb66ff kj::_::RunnableImpl<kj::_::TransformPromiseNodeBase::get(kj::_::ExceptionOrValue&)::$_4>::run() + 23
8   StubChainAdaptor                0x0000000111ee8983 kj::_::runCatchingExceptions(kj::_::Runnable&) + 28
9   StubChainAdaptor                0x0000000111eb4078 kj::_::TransformPromiseNodeBase::get(kj::_::ExceptionOrValue&) + 52
10  StubChainAdaptor                0x0000000111eb4ca5 kj::_::ChainPromiseNode::fire() + 67
11  StubChainAdaptor                0x0000000111eb523a non-virtual thunk to kj::_::ChainPromiseNode::fire() + 18
12  StubChainAdaptor                0x0000000111eb2d1f kj::EventLoop::turn() + 91
13  StubChainAdaptor                0x0000000111eb2c67 kj::EventLoop::run(unsigned int) + 39
14  VotingApp                       0x000000010fa782d5 QtEventPort::run() + 69
15  VotingApp                       0x000000010f9ccae4 QtEventPort::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) + 68
16  org.qt-project.QtCore           0x0000000110dcc9ec QObject::event(QEvent*) + 156
17  org.qt-project.QtWidgets        0x000000010ff41edd QApplicationPrivate::notify_helper(QObject*, QEvent*) + 269
18  org.qt-project.QtWidgets        0x000000010ff44822 QApplication::notify(QObject*, QEvent*) + 5906
19  org.qt-project.QtCore           0x0000000110da2aa4 QCoreApplication::notifyInternal2(QObject*, QEvent*) + 164
20  org.qt-project.QtCore           0x0000000110da36d8 QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) + 600
21  libqcocoa.dylib                 0x000000011487bd6e QCocoaEventDispatcherPrivate::processPostedEvents() + 190
22  libqcocoa.dylib                 0x000000011487c631 QCocoaEventDispatcherPrivate::postedEventsSourceCallback(void*) + 33
23  com.apple.CoreFoundation        0x00007fff97348a01 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
24  com.apple.CoreFoundation        0x00007fff9733ab8d __CFRunLoopDoSources0 + 269
25  com.apple.CoreFoundation        0x00007fff9733a1bf __CFRunLoopRun + 927
26  com.apple.CoreFoundation        0x00007fff97339bd8 CFRunLoopRunSpecific + 296
27  com.apple.HIToolbox             0x00007fff908ca56f RunCurrentEventLoopInMode + 235
28  com.apple.HIToolbox             0x00007fff908ca2ea ReceiveNextEventCommon + 431
29  com.apple.HIToolbox             0x00007fff908ca12b _BlockUntilNextEventMatchingListInModeWithFilter + 71
30  com.apple.AppKit                0x00007fff8906f8ab _DPSNextEvent + 978
31  com.apple.AppKit                0x00007fff8906ee58 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 346
32  com.apple.AppKit                0x00007fff89064af3 -[NSApplication run] + 594
33  libqcocoa.dylib                 0x000000011487b53f QCocoaEventDispatcher::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 2191
34  org.qt-project.QtCore           0x0000000110d9eeb1 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 401
35  org.qt-project.QtCore           0x0000000110da3115 QCoreApplication::exec() + 341
36  VotingApp                       0x000000010fa4cac7 main + 1719
37  VotingApp                       0x000000010f9b4f14 start + 52

Looking at this stack, it appears highly likely that we've got a dangling pointer. My guess is that the notifier is outliving the page it is intended to notify, so when the notification of updated results comes in from the server, the notifier attempts to update the details in the page, which is now destroyed, and we crash dereferencing a dangling pointer.