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

assert: "last < rowCount(parent)" in qabstractitemmodel.cpp #703

Closed
Sjors opened this issue Jan 24, 2023 · 11 comments · Fixed by #704
Closed

assert: "last < rowCount(parent)" in qabstractitemmodel.cpp #703

Sjors opened this issue Jan 24, 2023 · 11 comments · Fixed by #704
Labels
Bug Something isn't working

Comments

@Sjors
Copy link
Member

Sjors commented Jan 24, 2023

Some but not all of my (descriptor) wallets trigger the following crash, immediately when loading them.

GUI: ASSERT: "last < rowCount(parent)" in file itemmodels/qabstractitemmodel.cpp, line 2815

Happens on master @ fcff639 with a DEBUG=1 depends build, but regardless of the ./configure --debug flag). Intel macOS 13.1. Will try some other configurations.

Also tested against Homebrew qt 5.15.8 (depends is at 5.15.5), which doesn't produce the problem.

I tried bumping depends QT to 5.15.8 but this requires changing our patches, which I'm not sure how to do. Bumping QT is only a solution if the bug is in QT, not if it's on our end.

Interestingly I don't experience this bug in the v24.0.1 guix build, even though that uses the same QT version (since bitcoin/bitcoin#25719).

Random other project that ran into the same assert: https://invent.kde.org/utilities/kfind/-/merge_requests/1

@Sjors
Copy link
Member Author

Sjors commented Jan 24, 2023

Last bit of the log and lldb backtrace, when I open a wallet via the menu:

2023-01-24T12:51:11Z [qt-walletctrl] [***] Scanning current mempool transactions.
2023-01-24T12:51:11Z [qt-walletctrl] [***] Rescan completed in            4521ms
2023-01-24T12:51:11Z [qt-walletctrl] [***] setKeyPool.size() = ***
2023-01-24T12:51:11Z [qt-walletctrl] [***] mapWallet.size() = ***
2023-01-24T12:51:11Z [qt-walletctrl] [***] m_address_book.size() = ***
2023-01-24T12:51:12Z [main] GUI: ASSERT: "last < rowCount(parent)" in file itemmodels/qabstractitemmodel.cpp, line 2815
Process 69083 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00007ff81888822a libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`:
->  0x7ff81888822a <+10>: jae    0x7ff818888234            ; <+20>
    0x7ff81888822c <+12>: movq   %rax, %rdi
    0x7ff81888822f <+15>: jmp    0x7ff818881ce2            ; cerror_nocancel
    0x7ff818888234 <+20>: retq   
Target 0: (bitcoin-qt) stopped.

At this point the UI is still showing the Open Wallet modal with "Opening Wallet ****" and the progress bar at the start.

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
  * frame #0: 0x00007ff81888822a libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x00007ff8188bff7b libsystem_pthread.dylib`pthread_kill + 263
    frame #2: 0x00007ff818809ca5 libsystem_c.dylib`abort + 123
    frame #3: 0x000000010116c0d9 bitcoin-qt`qt_message_fatal((null)=<unavailable>, context=<unavailable>, message=<unavailable>) at qlogging.cpp:1914:5 [opt]
    frame #4: 0x0000000101712b48 bitcoin-qt`QMessageLogger::fatal(this=<unavailable>, msg=<unavailable>) const at qlogging.cpp:893:5 [opt]
    frame #5: 0x000000010171251f bitcoin-qt`qt_assert(assertion="last < rowCount(parent)", file="itemmodels/qabstractitemmodel.cpp", line=2815) at qglobal.cpp:3358:41 [opt]
    frame #6: 0x000000010171d21c bitcoin-qt`QAbstractItemModel::beginRemoveRows(QModelIndex const&, int, int) (.cold.2) at qabstractitemmodel.cpp:2815:5 [opt]
    frame #7: 0x000000010125a7fe bitcoin-qt`QAbstractItemModel::beginRemoveRows(this=0x0000600002598960, parent=0x00007ff7bfefc9a8, first=117, last=117) at qabstractitemmodel.cpp:2815:5 [opt]
    frame #8: 0x0000000101270262 bitcoin-qt`QSortFilterProxyModelPrivate::remove_proxy_interval(this=0x000000010864a0a0, source_to_proxy=0x00006000053e8130, proxy_to_source=0x00006000053e8120, proxy_start=117, proxy_end=117, proxy_parent=0x00007ff7bfefc9a8, orient=Vertical, emit_signal=<unavailable>) at qsortfilterproxymodel.cpp:784:16 [opt]
    frame #9: 0x000000010127013c bitcoin-qt`QSortFilterProxyModelPrivate::remove_source_items(this=0x000000010864a0a0, source_to_proxy=0x00006000053e8130, proxy_to_source=0x00006000053e8120, source_items=0x00007ff7bfefca58, source_parent=0x00007ff7bfefcb28, orient=Vertical, emit_signal=<unavailable>) at qsortfilterproxymodel.cpp:765:9 [opt]
    frame #10: 0x0000000101271d52 bitcoin-qt`QSortFilterProxyModelPrivate::handle_filter_changed(this=0x000000010864a0a0, source_to_proxy=0x00006000053e8130, proxy_to_source=0x00006000053e8120, source_parent=0x00007ff7bfefcb28, orient=Vertical) at qsortfilterproxymodel.cpp:1344:9 [opt]
    frame #11: 0x0000000101271a53 bitcoin-qt`QSortFilterProxyModelPrivate::filter_changed(this=0x000000010864a0a0, source_parent=0x00007ff7bfefcb28) at qsortfilterproxymodel.cpp:1277:30 [opt]
    frame #12: 0x000000010127657a bitcoin-qt`QSortFilterProxyModel::invalidateFilter(this=<unavailable>) at qsortfilterproxymodel.cpp:3024:8 [opt]
    frame #13: 0x000000010012d633 bitcoin-qt`TransactionFilterProxy::setShowInactive(this=<unavailable>, _showInactive=<unavailable>) at transactionfilterproxy.cpp:99:5 [opt]
    frame #14: 0x00000001000e86d6 bitcoin-qt`OverviewPage::setWalletModel(this=0x000060001a9272c0, model=0x0000600003d10c30) at overviewpage.cpp:268:17 [opt]
    frame #15: 0x000000010018cc1e bitcoin-qt`WalletView::WalletView(this=0x000060000322f600, wallet_model=<unavailable>, _platformStyle=0x000060000000c9e0, parent=<unavailable>) at walletview.cpp:41:19 [opt]
    frame #16: 0x000000010018e6ff bitcoin-qt`WalletView::WalletView(this=<unavailable>, wallet_model=<unavailable>, _platformStyle=<unavailable>, parent=<unavailable>) at walletview.cpp:36:1 [opt]
    frame #17: 0x000000010003167c bitcoin-qt`BitcoinGUI::addWallet(this=0x00000001067a0b60, walletModel=0x0000600003d10c30) at bitcoingui.cpp:697:35 [opt]
    frame #18: 0x0000000100036ec4 bitcoin-qt`WalletController* auto GUIUtil::ExceptionSafeConnect<WalletController*, void (WalletController::*)(WalletModel*), BitcoinGUI*, void (BitcoinGUI::*)(WalletModel*)>(this=0x000060000964e440, args=<unavailable>)(WalletModel*), BitcoinGUI*, void (BitcoinGUI::*)(WalletModel*), Qt::ConnectionType)::'lambda'(auto&&...)::operator()<WalletModel*&>('lambda'(auto&&...)) const at guiutil.h:400:21 [opt]
    frame #19: 0x0000000100036e57 bitcoin-qt`QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<WalletModel*>, void, auto GUIUtil::ExceptionSafeConnect<WalletController*, void (WalletController::*)(WalletModel*), BitcoinGUI*, void (BitcoinGUI::*)(WalletModel*)>(WalletController*, void (WalletController::*)(WalletModel*), BitcoinGUI*, void (BitcoinGUI::*)(WalletModel*), Qt::ConnectionType)::'lambda'(auto&&...)>::call(f=<unavailable>, arg=0x000060001aa98cf8)(WalletModel*), BitcoinGUI*, void (BitcoinGUI::*)(WalletModel*)>(WalletController*, void (WalletController::*)(WalletModel*), BitcoinGUI*, void (BitcoinGUI::*)(WalletModel*), Qt::ConnectionType)::'lambda'(auto&&...)>&, void**) at qobjectdefs_impl.h:146:13 [opt]
    frame #20: 0x0000000100036dd2 bitcoin-qt`_ZN9QtPrivate7FunctorIZN7GUIUtil20ExceptionSafeConnectIP16WalletControllerMS3_FvP11WalletModelEP10BitcoinGUIMS9_FvS6_EEEDaT_T0_T1_T2_N2Qt14ConnectionTypeEEUlDpOT_E_Li1EE4callINS_4ListIJS6_EEEvEEvRSN_PvPST_(f=<unavailable>, (null)=<unavailable>, arg=<unavailable>) at qobjectdefs_impl.h:256:13 [opt]
    frame #21: 0x0000000100036d4d bitcoin-qt`QtPrivate::QFunctorSlotObject<auto GUIUtil::ExceptionSafeConnect<WalletController*, void (WalletController::*)(WalletModel*), BitcoinGUI*, void (BitcoinGUI::*)(WalletModel*)>(WalletController*, void (WalletController::*)(WalletModel*), BitcoinGUI*, void (BitcoinGUI::*)(WalletModel*), Qt::ConnectionType)::'lambda'(auto&&...), 1, QtPrivate::List<WalletModel*>, void>::impl(which=<unavailable>, this_=<unavailable>, r=<unavailable>, a=<unavailable>, ret=<unavailable>) at qobjectdefs_impl.h:443:17 [opt]
    frame #22: 0x00000001012aa288 bitcoin-qt`QtPrivate::QSlotObjectBase::call(this=<unavailable>, r=<unavailable>, a=<unavailable>) at qobjectdefs_impl.h:398:51 [opt]
    frame #23: 0x00000001012aa215 bitcoin-qt`QMetaCallEvent::placeMetaCall(this=0x000060001aa98cb0, object=0x00000001067a0b60) at qobject.cpp:615:21 [opt]
    frame #24: 0x00000001012ab2e1 bitcoin-qt`QObject::event(this=0x00000001067a0b60, e=0x000060001aa98cb0) at qobject.cpp:1314:18 [opt]
    frame #25: 0x00000001013cb758 bitcoin-qt`QWidget::event(this=0x00000001067a0b60, event=0x000060001aa98cb0) at qwidget.cpp:9094:25 [opt]
    frame #26: 0x000000010149e100 bitcoin-qt`QMainWindow::event(this=0x00000001067a0b60, event=0x000060001aa98cb0) at qmainwindow.cpp:1341:21 [opt]
    frame #27: 0x000000010139726a bitcoin-qt`QApplicationPrivate::notify_helper(this=<unavailable>, receiver=0x00000001067a0b60, e=0x000060001aa98cb0) at qapplication.cpp:3637:26 [opt]
    frame #28: 0x0000000101399628 bitcoin-qt`QApplication::notify(this=<unavailable>, receiver=<unavailable>, e=<unavailable>) at qapplication.cpp:0 [opt]
    frame #29: 0x000000010128c77a bitcoin-qt`QCoreApplication::notifyInternal2(receiver=0x00000001067a0b60, event=0x000060001aa98cb0) at qcoreapplication.cpp:1064:18 [opt]
    frame #30: 0x000000010128cf12 bitcoin-qt`QCoreApplication::sendEvent(receiver=<unavailable>, event=<unavailable>) at qcoreapplication.cpp:1462:12 [opt]
    frame #31: 0x000000010128d725 bitcoin-qt`QCoreApplicationPrivate::sendPostedEvents(receiver=<unavailable>, event_type=0, data=<unavailable>) at qcoreapplication.cpp:1821:9 [opt]
    frame #32: 0x000000010128ce45 bitcoin-qt`QCoreApplication::sendPostedEvents(receiver=<unavailable>, event_type=<unavailable>) at qcoreapplication.cpp:1680:5 [opt]
    frame #33: 0x0000000100eeecef bitcoin-qt`QCocoaEventDispatcherPrivate::processPostedEvents(this=0x0000000108204e10) at qcocoaeventdispatcher.mm:904:9 [opt]
    frame #34: 0x0000000100eef3e8 bitcoin-qt`QCocoaEventDispatcherPrivate::postedEventsSourceCallback(info=0x0000000108204e10) at qcocoaeventdispatcher.mm:927:8 [opt]
    frame #35: 0x00007ff81899bb98 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #36: 0x00007ff81899bb47 CoreFoundation`__CFRunLoopDoSource0 + 157
    frame #37: 0x00007ff81899b921 CoreFoundation`__CFRunLoopDoSources0 + 212
    frame #38: 0x00007ff81899a59b CoreFoundation`__CFRunLoopRun + 929
    frame #39: 0x00007ff818999b80 CoreFoundation`CFRunLoopRunSpecific + 560
    frame #40: 0x00007ff8222de766 HIToolbox`RunCurrentEventLoopInMode + 292
    frame #41: 0x00007ff8222de576 HIToolbox`ReceiveNextEventCommon + 679
    frame #42: 0x00007ff8222de2b3 HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 70
    frame #43: 0x00007ff81bae5f33 AppKit`_DPSNextEvent + 909
    frame #44: 0x00007ff81bae4db4 AppKit`-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1219
    frame #45: 0x0000000100eee950 bitcoin-qt`qt_mac_waitForMoreEvents(runLoopMode=<unavailable>) at qcocoaeventdispatcher.mm:342:22 [opt]
    frame #46: 0x0000000100eee034 bitcoin-qt`QCocoaEventDispatcher::processEvents(this=<unavailable>, flags=(i = 36)) at qcocoaeventdispatcher.mm:411:21 [opt]
    frame #47: 0x0000000101289b7f bitcoin-qt`QEventLoop::processEvents(this=0x00007ff7bfefef08, flags=(i = 36)) at qeventloop.cpp:139:55 [opt]
    frame #48: 0x0000000101289ca7 bitcoin-qt`QEventLoop::exec(this=0x00007ff7bfefef08, flags=(i = 0)) at qeventloop.cpp:232:9 [opt]
    frame #49: 0x000000010128ccef bitcoin-qt`QCoreApplication::exec() at qcoreapplication.cpp:1375:32 [opt]
    frame #50: 0x0000000100f2ed76 bitcoin-qt`QGuiApplication::exec() at qguiapplication.cpp:1867:12 [opt]
    frame #51: 0x0000000101398279 bitcoin-qt`QApplication::exec() at qapplication.cpp:2829:12 [opt]
    frame #52: 0x0000000100014c3f bitcoin-qt`GuiMain(argc=2, argv=<unavailable>) at bitcoin.cpp:692:13 [opt]
    frame #53: 0x000000010000762f bitcoin-qt`main(argc=<unavailable>, argv=<unavailable>) at main.cpp:24:12 [opt]
    frame #54: 0x00007ff81858d310 dyld`start + 2432

@Sjors
Copy link
Member Author

Sjors commented Jan 24, 2023

cc @achow101: maybe this error is triggered by some data consistency issue (in the address book?) that we could perhaps catch earlier on.

@john-moffett
Copy link
Contributor

I think this has something to do with the way we're displaying the list of transactions on the overview page. It takes the full list of wallet transactions and artificially limits it to five items (NUM_ITEMS is 5):

gui/src/qt/overviewpage.cpp

Lines 262 to 269 in 50ac8f5

// Set up transaction list
filter.reset(new TransactionFilterProxy());
filter->setSourceModel(model->getTransactionTableModel());
filter->setLimit(NUM_ITEMS);
filter->setDynamicSortFilter(true);
filter->setSortRole(Qt::EditRole);
filter->setShowInactive(false);
filter->sort(TransactionTableModel::Date, Qt::DescendingOrder);

The proxy filter limits the data to only show the most recent five rows by overriding the rowCount method:

void TransactionFilterProxy::setLimit(int limit)
{
this->limitRows = limit;
}
void TransactionFilterProxy::setShowInactive(bool _showInactive)
{
this->showInactive = _showInactive;
invalidateFilter();
}
int TransactionFilterProxy::rowCount(const QModelIndex &parent) const
{
if(limitRows != -1)
{
return std::min(QSortFilterProxyModel::rowCount(parent), limitRows);
}
else
{
return QSortFilterProxyModel::rowCount(parent);
}
}

While it works for the most part, I think, strictly speaking, it violates what rowCount ought to be returning, which is the count of the rows after they're filtered by filterAcceptsRow. However, the violation is only caught during debug builds, since Q_ASSERT does nothing for release builds and rowCount(parent) doesn't actually have to be greater than last. I expect it should trigger any time the wallet has more than five transactions, though it's possible that it only triggers if the wallet has more than five transactions and at least one of them was marked as conflicted (since that's what ShowInactive removes).

I suppose you could try moving line 265 to after line 268 (in overviewpage.cpp) and see if that avoids it, but it's not exactly a great solution.

@Sjors
Copy link
Member Author

Sjors commented Jan 25, 2023

I created a fresh Signet wallet and obtained a bunch of coins from the faucet. Receiving the 6th transaction while I was on the transaction screen did not crash, nor did returning to the home screen or restarting and then loading that wallet again.

I then sent a transaction to myself (same wallet) and bumped the fee. This didn't trigger a crash, but strangely the unbumped transaction wasn't marked as conflicting either. I then waited for confirmation. It got marked as conflicted, but no crash. Going back to the home tab also did not trigger a crash. Neither did stopping and restarting the node.

I proceeded to create more transactions, enough to cause the conflicted and replaced transaction to no longer be on the home page. No crash (after confirmation and restart).

@john-moffett
Copy link
Contributor

Hmm, interesting. I still think it has something to do with the (mis)use of rowCount, but without a way to reproduce, I'm mostly just guessing. Definitely worth looking into, so I'll try my best to trigger it. If you can reproduce it with a shareable wallet / network, please pass them along.

@Sjors
Copy link
Member Author

Sjors commented Jan 25, 2023

I think cleaning up this particular code might just help the bug go away, so it's probably worth a try. I'll see I can run into it in another signet wallet.

@john-moffett
Copy link
Contributor

john-moffett commented Jan 25, 2023

OK, I've managed to reproduce the bug by conflicting out several transactions on regtest and Signet.

It turns out that I was largely correct, but missed some details. It is the case that setShowInactive(false) which calls invalidateFilter() will cause the proxy model to go through all the transactions in the source and see which ones are conflicted. It'll then try to remove any such rows from the proxy list (which at this point is still identical to the source list). The Q_ASSERT just does a range check to see if the element to be removed is outside of the (apparent) range, so it calls rowCount on our subclass of QSortFilterProxyModel, which says the count is min(5, actual). So if the index it's trying to remove is >= 5, the assert will always fail. (The actual 'removal' happens to the proxy-to-source mapping, which is managed independently from rowCount, so that's why it only crashes on Qt DEBUG builds.)

Why did it not trigger for you, then?

The source transaction list is sorted in the GUI by txid:

/* Local cache of wallet.
* As it is in the same order as the CWallet, by definition
* this is sorted by sha256.
*/
QList<TransactionRecord> cachedWallet;

(Note that the comment is incorrect. The transactions are stored in the node's wallet primarily as a std::unordered_map, but with an ordered view based on time, not hash):

gui/src/wallet/wallet.h

Lines 397 to 402 in ab98673

/** Map from txid to CWalletTx for all transactions this wallet is
* interested in, including received and sent transactions. */
std::unordered_map<uint256, CWalletTx, SaltedTxidHasher> mapWallet GUARDED_BY(cs_wallet);
typedef std::multimap<int64_t, CWalletTx*> TxItems;
TxItems wtxOrdered;

Anyway, any conflicted transaction(s) must have an index >= 5 when sorted by txid for the assert to trigger. Furthermore, it's only triggered when the wallet is first loaded in the GUI, since invalidateFilter isn't ever subsequently called for the overview page.

An easy way to reproduce the bug is to create a transaction to yourself and fee-bump it 6 times, then wait for a block to come, which will make 6 conflicted transactions, guaranteeing that at least one will have an index >= 5. Then restart the GUI or close and re-open the wallet and it should crash.

How to fix?

The easiest solution is to re-order the way the filter is constructed in overviewpage.cpp. One way is to move filter->setLimit to after filter->setShowInactive. I can confirm that will avoid the assert failure.

Edit: It'll only avoid the assert failure on startup. Any subsequent calls resulting in the proxy filter having rows removed (ie - new conflicted-out transactions) will trigger the assert. I don't think this 'solution' is sound.

A more complete and correct solution is, unfortunately, more involved. There doesn't seem to be a straightforward way of limiting a QListView to only show the first few rows. I suppose we could subscribe it to changes of the proxy model and call setRowHidden(int row, bool hide) on all the rows accordingly. I'm not sure how that would affect performance if a wallet has a ton of transactions.

I'm happy to open a PR for either approach.

@Sjors
Copy link
Member Author

Sjors commented Jan 25, 2023

@john-moffett great find! Happy to test fixes. Not sure what the best way is.

@hebasto any thoughts?

@john-moffett
Copy link
Contributor

Edited to rule out the 'simple solution', since it actually does get triggered on subsequent removals -- not by invalidateFilter, but by the usual signal update. Stack trace as follows:


* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00007ff8104b222a libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`:
->  0x7ff8104b222a <+10>: jae    0x7ff8104b2234            ; <+20>
    0x7ff8104b222c <+12>: movq   %rax, %rdi
    0x7ff8104b222f <+15>: jmp    0x7ff8104abce2            ; cerror_nocancel
    0x7ff8104b2234 <+20>: retq   
Target 0: (bitcoin-qt) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
  * frame #0: 0x00007ff8104b222a libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x00007ff8104e9f7b libsystem_pthread.dylib`pthread_kill + 263
    frame #2: 0x00007ff810433ca5 libsystem_c.dylib`abort + 123
    frame #3: 0x0000000101bd9199 bitcoin-qt`qt_message_fatal((null)=<unavailable>, context=<unavailable>, message=<unavailable>) at qlogging.cpp:1914:5 [opt]
    frame #4: 0x00000001022d8f18 bitcoin-qt`QMessageLogger::fatal(this=<unavailable>, msg=<unavailable>) const at qlogging.cpp:893:5 [opt]
    frame #5: 0x00000001022d894f bitcoin-qt`qt_assert(assertion="last < rowCount(parent)", file="itemmodels/qabstractitemmodel.cpp", line=2815) at qglobal.cpp:3358:41 [opt]
    frame #6: 0x00000001022e353c bitcoin-qt`QAbstractItemModel::beginRemoveRows(QModelIndex const&, int, int) (.cold.2) at qabstractitemmodel.cpp:2815:5 [opt]
    frame #7: 0x0000000101cc646e bitcoin-qt`QAbstractItemModel::beginRemoveRows(this=0x0000600002165180, parent=0x00007ff7bfefbe58, first=2, last=8) at qabstractitemmodel.cpp:2815:5 [opt]
    frame #8: 0x0000000101cdb802 bitcoin-qt`QSortFilterProxyModelPrivate::remove_proxy_interval(this=0x000000010873e010, source_to_proxy=0x0000600000ce19c0, proxy_to_source=0x0000600000ce19b0, proxy_start=2, proxy_end=8, proxy_parent=0x00007ff7bfefbe58, orient=Vertical, emit_signal=<unavailable>) at qsortfilterproxymodel.cpp:784:16 [opt]
    frame #9: 0x0000000101cdb6dc bitcoin-qt`QSortFilterProxyModelPrivate::remove_source_items(this=0x000000010873e010, source_to_proxy=0x0000600000ce19c0, proxy_to_source=0x0000600000ce19b0, source_items=0x00007ff7bfefbfa0, source_parent=0x00007ff7bfefbf80, orient=Vertical, emit_signal=<unavailable>) at qsortfilterproxymodel.cpp:765:9 [opt]
    frame #10: 0x0000000101cdd8d1 bitcoin-qt`QSortFilterProxyModelPrivate::_q_sourceDataChanged(this=0x000000010873e010, source_top_left=<unavailable>, source_bottom_right=<unavailable>, roles=0x00007ff7bfefc280) at qsortfilterproxymodel.cpp:1446:13 [opt]
    frame #11: 0x0000000101ce222f bitcoin-qt`QSortFilterProxyModel::qt_static_metacall(_o=<unavailable>, _c=<unavailable>, _id=<unavailable>, _a=0x00007ff7bfefc150) at moc_qsortfilterproxymodel.cpp:275:32 [opt]
    frame #12: 0x0000000101d1ad24 bitcoin-qt`void doActivate<false>(sender=0x0000600002160690, signal_index=<unavailable>, argv=0x00007ff7bfefc150) at qobject.cpp:3898:21 [opt]
    frame #13: 0x0000000101d1a20f bitcoin-qt`QMetaObject::activate(sender=0x0000600002160690, m=<unavailable>, local_signal_index=0, argv=0x00007ff7bfefc150) at qobject.cpp:3946:9 [opt]
    frame #14: 0x0000000101cc948c bitcoin-qt`QAbstractItemModel::dataChanged(this=<unavailable>, _t1=<unavailable>, _t2=<unavailable>, _t3=<unavailable>) at moc_qabstractitemmodel.cpp:557:5 [opt]
    frame #15: 0x0000000100221026 bitcoin-qt`TransactionTableModel::updateConfirmations(this=0x0000600002160690) at transactiontablemodel.cpp:293:12
    frame #16: 0x000000010026c14c bitcoin-qt`WalletModel::pollBalanceChanged(this=0x0000600003d08a50) at walletmodel.cpp:117:36
    frame #17: 0x00000001002749d7 bitcoin-qt`WalletModel* auto GUIUtil::ExceptionSafeConnect<WalletModel*, void (WalletModel::*)(), WalletModel*, void (WalletModel::*)()>(this=0x0000600000cd93f0)(), WalletModel*, void (WalletModel::*)(), Qt::ConnectionType)::'lambda'(auto&&...)::operator()<>('lambda'(auto&&...)) const at guiutil.h:400:21
    frame #18: 0x00000001002748fb bitcoin-qt`QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, auto GUIUtil::ExceptionSafeConnect<WalletModel*, void (WalletModel::*)(), WalletModel*, void (WalletModel::*)()>(WalletModel*, void (WalletModel::*)(), WalletModel*, void (WalletModel::*)(), Qt::ConnectionType)::'lambda'(auto&&...)>::call(f=0x0000600000cd93f0, arg=0x00007ff7bfefc8d8)(), WalletModel*, void (WalletModel::*)()>(WalletModel*, void (WalletModel::*)(), WalletModel*, void (WalletModel::*)(), Qt::ConnectionType)::'lambda'(auto&&...)>&, void**) at qobjectdefs_impl.h:146:13
    frame #19: 0x0000000100274853 bitcoin-qt`_ZN9QtPrivate7FunctorIZN7GUIUtil20ExceptionSafeConnectIP11WalletModelMS3_FvvES4_S6_EEDaT_T0_T1_T2_N2Qt14ConnectionTypeEEUlDpOT_E_Li0EE4callINS_4ListIJEEEvEEvRSH_PvPSN_(f=0x0000600000cd93f0, (null)=0x0000600003d08a50, arg=0x00007ff7bfefc8d8) at qobjectdefs_impl.h:256:13
    frame #20: 0x0000000100274793 bitcoin-qt`QtPrivate::QFunctorSlotObject<auto GUIUtil::ExceptionSafeConnect<WalletModel*, void (WalletModel::*)(), WalletModel*, void (WalletModel::*)()>(WalletModel*, void (WalletModel::*)(), WalletModel*, void (WalletModel::*)(), Qt::ConnectionType)::'lambda'(auto&&...), 0, QtPrivate::List<>, void>::impl(which=1, this_=0x0000600000cd93e0, r=0x0000600003d08a50, a=0x00007ff7bfefc8d8, ret=0x0000000000000000) at qobjectdefs_impl.h:443:17
    frame #21: 0x0000000101d14bc8 bitcoin-qt`QtPrivate::QSlotObjectBase::call(this=<unavailable>, r=<unavailable>, a=<unavailable>) at qobjectdefs_impl.h:398:51 [opt]
    frame #22: 0x0000000101d1ac97 bitcoin-qt`void doActivate<false>(sender=0x0000600003d08a50, signal_index=<unavailable>, argv=0x00007ff7bfefc8d8) at qobject.cpp:3886:26 [opt]
    frame #23: 0x0000000101d1a20f bitcoin-qt`QMetaObject::activate(sender=0x0000600003d08a50, m=<unavailable>, local_signal_index=9, argv=0x0000000000000000) at qobject.cpp:3946:9 [opt]
    frame #24: 0x00000001002dbe77 bitcoin-qt`WalletModel::timerTimeout(this=0x0000600003d08a50) at moc_walletmodel.cpp:355:5
    frame #25: 0x0000000100288c9d bitcoin-qt`QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (WalletModel::*)()>::call(f=40 be 2d 00 01 00 00 00 00 00 00 00 00 00 00 00, o=0x0000600003d08a50, arg=0x00007ff7bfefcbc0)(), WalletModel*, void**) at qobjectdefs_impl.h:152:13
    frame #26: 0x0000000100288b8f bitcoin-qt`void QtPrivate::FunctionPointer<void (WalletModel::*)()>::call<QtPrivate::List<>, void>(f=40 be 2d 00 01 00 00 00 00 00 00 00 00 00 00 00, o=0x0000600003d08a50, arg=0x00007ff7bfefcbc0)(), WalletModel*, void**) at qobjectdefs_impl.h:185:13
    frame #27: 0x0000000100288a65 bitcoin-qt`QtPrivate::QSlotObject<void (WalletModel::*)(), QtPrivate::List<>, void>::impl(which=1, this_=0x00006000002932c0, r=0x0000600003d08a50, a=0x00007ff7bfefcbc0, ret=0x0000000000000000) at qobjectdefs_impl.h:418:17
    frame #28: 0x0000000101d14bc8 bitcoin-qt`QtPrivate::QSlotObjectBase::call(this=<unavailable>, r=<unavailable>, a=<unavailable>) at qobjectdefs_impl.h:398:51 [opt]
    frame #29: 0x0000000101d1ac97 bitcoin-qt`void doActivate<false>(sender=0x00006000002a0160, signal_index=<unavailable>, argv=0x00007ff7bfefcbc0) at qobject.cpp:3886:26 [opt]
    frame #30: 0x0000000101d1a20f bitcoin-qt`QMetaObject::activate(sender=0x00006000002a0160, m=<unavailable>, local_signal_index=0, argv=0x00007ff7bfefcbc0) at qobject.cpp:3946:9 [opt]
    frame #31: 0x0000000101d212c8 bitcoin-qt`QTimer::timeout(this=<unavailable>, _t1=QPrivateSignal @ 0x00007ff7bfefcbb8) at moc_qtimer.cpp:205:5 [opt]
    frame #32: 0x0000000101d2127c bitcoin-qt`QTimer::timerEvent(this=0x00006000002a0160, e=<unavailable>) at qtimer.cpp:257:14 [opt]
    frame #33: 0x0000000101d159da bitcoin-qt`QObject::event(this=0x00006000002a0160, e=0x00007ff7bfefcfb0) at qobject.cpp:1291:9 [opt]
    frame #34: 0x0000000101e00d1a bitcoin-qt`QApplicationPrivate::notify_helper(this=<unavailable>, receiver=0x00006000002a0160, e=0x00007ff7bfefcfb0) at qapplication.cpp:3637:26 [opt]
    frame #35: 0x0000000101e03098 bitcoin-qt`QApplication::notify(this=<unavailable>, receiver=<unavailable>, e=<unavailable>) at qapplication.cpp:0 [opt]
    frame #36: 0x0000000101cf78ba bitcoin-qt`QCoreApplication::notifyInternal2(receiver=0x00006000002a0160, event=0x00007ff7bfefcfb0) at qcoreapplication.cpp:1064:18 [opt]
    frame #37: 0x0000000101cf8052 bitcoin-qt`QCoreApplication::sendEvent(receiver=<unavailable>, event=<unavailable>) at qcoreapplication.cpp:1462:12 [opt]
    frame #38: 0x0000000101d4a963 bitcoin-qt`QTimerInfoList::activateTimers(this=0x0000000108507ab8) at qtimerinfo_unix.cpp:643:13 [opt]
    frame #39: 0x000000010195cb63 bitcoin-qt`QCocoaEventDispatcherPrivate::processTimers(this=0x0000000108507a50) at qcocoaeventdispatcher.mm:131:35 [opt]
    frame #40: 0x000000010195cb3e bitcoin-qt`QCocoaEventDispatcherPrivate::activateTimersSourceCallback(info=0x0000000108507a50) at qcocoaeventdispatcher.mm:125:8 [opt]
    frame #41: 0x00007ff8105c5b78 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    frame #42: 0x00007ff8105c5b27 CoreFoundation`__CFRunLoopDoSource0 + 157
    frame #43: 0x00007ff8105c5961 CoreFoundation`__CFRunLoopDoSources0 + 308
    frame #44: 0x00007ff8105c457b CoreFoundation`__CFRunLoopRun + 929
    frame #45: 0x00007ff8105c3b60 CoreFoundation`CFRunLoopRunSpecific + 560
    frame #46: 0x00007ff819f11766 HIToolbox`RunCurrentEventLoopInMode + 292
    frame #47: 0x00007ff819f11576 HIToolbox`ReceiveNextEventCommon + 679
    frame #48: 0x00007ff819f112b3 HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 70
    frame #49: 0x00007ff813714293 AppKit`_DPSNextEvent + 909
    frame #50: 0x00007ff813713114 AppKit`-[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1219
    frame #51: 0x00007ff813705757 AppKit`-[NSApplication run] + 586
    frame #52: 0x000000010195d639 bitcoin-qt`QCocoaEventDispatcher::processEvents(this=<unavailable>, flags=(i = 36)) at qcocoaeventdispatcher.mm:437:17 [opt]
    frame #53: 0x0000000101cf4e4f bitcoin-qt`QEventLoop::processEvents(this=0x00007ff7bfefe7b8, flags=(i = 36)) at qeventloop.cpp:139:55 [opt]
    frame #54: 0x0000000101cf4f77 bitcoin-qt`QEventLoop::exec(this=0x00007ff7bfefe7b8, flags=(i = 0)) at qeventloop.cpp:232:9 [opt]
    frame #55: 0x0000000101cf7e2f bitcoin-qt`QCoreApplication::exec() at qcoreapplication.cpp:1375:32 [opt]
    frame #56: 0x000000010199dca6 bitcoin-qt`QGuiApplication::exec() at qguiapplication.cpp:1867:12 [opt]
    frame #57: 0x0000000101e01ce9 bitcoin-qt`QApplication::exec() at qapplication.cpp:2829:12 [opt]
    frame #58: 0x0000000100020ab8 bitcoin-qt`GuiMain(argc=9, argv=0x00007ff7bfeff328) at bitcoin.cpp:692:13
    frame #59: 0x0000000100009134 bitcoin-qt`main(argc=9, argv=0x00007ff7bfeff328) at main.cpp:24:12
    frame #60: 0x00007ff8101b7310 dyld`start + 2432

The second solution still ought to work.

@hebasto
Copy link
Member

hebasto commented Feb 1, 2023

Confirming the bug on the master branch.

@hebasto
Copy link
Member

hebasto commented Feb 2, 2023

Observing the same bug on v24.0.1.

Interestingly I don't experience this bug in the v24.0.1 guix build

Because guix builds use release, not debug, dependencies.

@hebasto hebasto added this to the 24.1 milestone Feb 2, 2023
@hebasto hebasto removed this from the 24.1 milestone Feb 2, 2023
@hebasto hebasto closed this as completed in 526f67a Feb 2, 2023
@bitcoin-core bitcoin-core locked and limited conversation to collaborators Feb 2, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants