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

Crash when switching between different I2P torrents with peers tab open #18741

Closed
Vort opened this issue Mar 21, 2023 · 10 comments · Fixed by #18753
Closed

Crash when switching between different I2P torrents with peers tab open #18741

Vort opened this issue Mar 21, 2023 · 10 comments · Fixed by #18753
Assignees
Labels
Crash GUI GUI-related issues/changes
Milestone

Comments

@Vort
Copy link
Contributor

Vort commented Mar 21, 2023

qBittorrent & operating system versions

qBittorrent: e570ba7
Operating system: Windows 7 SP1 x64
Qt: 5.15.8
libtorrent-rasterbar: 84f53312df29a9389c6196918a977f08727025e4

What is the problem?

Crash happens when I select different torrent from list.

Steps to reproduce

  1. Enable I2P.
  2. Add two I2P torrents.
  3. Restart qBittorrent.
  4. Select Peers tab.
  5. Click on first torrent, click on second torrent, click on first torrent, ... until crash happens.

Additional context

Crash happens on this line, inside row() function:

m_listModel->removeRow(item->row());

Here is the stack trace:

ntdll!ZwWaitForMultipleObjects 0x00000000773692ca
KERNELBASE!GetCurrentProcess 0x000007fefd151420
WaitForMultipleObjectsEx 0x0000000077101143
WinExec 0x000000007717b615
WinExec 0x000000007717b797
WinExec 0x000000007717b7ef
UnhandledExceptionFilter 0x000000007717ba0c
ntdll!longjmp 0x0000000077378515
ntdll!__C_specific_handler 0x0000000077356798
ntdll!.chkstk 0x000000007736b41d
ntdll!RtlInitializeResource 0x000000007733f77a
ntdll!KiUserExceptionDispatcher 0x000000007736aabe
QStandardItem::row() const 0x000007fed5021f37
PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4::operator()(QVector<BitTorrent::PeerInfo> const&) const peerlistwidget.cpp:425
std::__1::__invoke[abi:v15007]<PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4&, QVector<BitTorrent::PeerInfo> >(PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4&, QVector<BitTorrent::PeerInfo>&&) invoke.h:394
std::__1::__invoke_void_return_wrapper<void, true>::__call<PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4&, QVector<BitTorrent::PeerInfo> >(PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4&, QVector<BitTorrent::PeerInfo>&&) invoke.h:479
std::__1::__function::__alloc_func<PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4, std::__1::allocator<PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4>, void (QVector<BitTorrent::PeerInfo>)>::operator()[abi:v15007](QVector<BitTorrent::PeerInfo>&&) function.h:185
std::__1::__function::__func<PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4, std::__1::allocator<PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4>, void (QVector<BitTorrent::PeerInfo>)>::operator()(QVector<BitTorrent::PeerInfo>&&) function.h:359
std::__1::__function::__value_func<void (QVector<BitTorrent::PeerInfo>)>::operator()[abi:v15007](QVector<BitTorrent::PeerInfo>&&) const function.h:512
std::__1::function<void (QVector<BitTorrent::PeerInfo>)>::operator()(QVector<BitTorrent::PeerInfo>) const function.h:1197
BitTorrent::TorrentImpl::invokeAsync<BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)> >(BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::{lambda()#1}::operator()()::{lambda()#1}::operator()() const torrentimpl.cpp:2753
QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, BitTorrent::TorrentImpl::invokeAsync<BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)> >(BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::{lambda()#1}::operator()()::{lambda()#1}>::call(BitTorrent::TorrentImpl::invokeAsync<BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)> >(BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::{lambda()#1}::operator()()::{lambda()#1}&, void**) qobjectdefs_impl.h:146
QtPrivate::Functor<BitTorrent::TorrentImpl::invokeAsync<BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)> >(BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::{lambda()#1}::operator()()::{lambda()#1}, 0>::call<QtPrivate::List<>, void>(BitTorrent::TorrentImpl::invokeAsync<BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)> >(BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::{lambda()#1}::operator()()::{lambda()#1}&, void*, void**) qobjectdefs_impl.h:256
QtPrivate::QFunctorSlotObject<BitTorrent::TorrentImpl::invokeAsync<BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)> >(BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::{lambda()#1}::operator()()::{lambda()#1}, 0, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) qobjectdefs_impl.h:443
QMetaCallEvent::placeMetaCall(QObject*) 0x000007fed6d0429e
QObject::event(QEvent*) 0x000007fed6d05781
QApplicationPrivate::notify_helper(QObject*, QEvent*) 0x000007fed5cdc613
QApplication::notify(QObject*, QEvent*) 0x000007fed5cdd893
QCoreApplication::notifyInternal2(QObject*, QEvent*) 0x000007fed6cdd962
QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) 0x000007fed6cde7ad
QWindowsGuiEventDispatcher::sendPostedEvents() 0x000007fed7dc12fe
QEventDispatcherWin32::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) 0x000007fed6d31b8c
QWindowsGuiEventDispatcher::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) 0x000007fed7dc12e5
QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) 0x000007fed6cdabd6
QDialog::exec() 0x000007fed5ec82d4
(anonymous namespace)::abnormalExitHandler signalhandler.cpp:111
_gnu_exception_handler 0x000000013f744e80
ntdll!__C_specific_handler 0x0000000077356798
ntdll!.chkstk 0x000000007736b41d
ntdll!RtlInitializeResource 0x000000007733f77a
ntdll!KiUserExceptionDispatcher 0x000000007736aabe
QStandardItem::row() const 0x000007fed5021f51
PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4::operator()(QVector<BitTorrent::PeerInfo> const&) const peerlistwidget.cpp:425
std::__1::__invoke[abi:v15007]<PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4&, QVector<BitTorrent::PeerInfo> >(PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4&, QVector<BitTorrent::PeerInfo>&&) invoke.h:394
std::__1::__invoke_void_return_wrapper<void, true>::__call<PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4&, QVector<BitTorrent::PeerInfo> >(PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4&, QVector<BitTorrent::PeerInfo>&&) invoke.h:479
std::__1::__function::__alloc_func<PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4, std::__1::allocator<PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4>, void (QVector<BitTorrent::PeerInfo>)>::operator()[abi:v15007](QVector<BitTorrent::PeerInfo>&&) function.h:185
std::__1::__function::__func<PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4, std::__1::allocator<PeerListWidget::loadPeers(BitTorrent::Torrent const*)::$_4>, void (QVector<BitTorrent::PeerInfo>)>::operator()(QVector<BitTorrent::PeerInfo>&&) function.h:359
std::__1::__function::__value_func<void (QVector<BitTorrent::PeerInfo>)>::operator()[abi:v15007](QVector<BitTorrent::PeerInfo>&&) const function.h:512
std::__1::function<void (QVector<BitTorrent::PeerInfo>)>::operator()(QVector<BitTorrent::PeerInfo>) const function.h:1197
BitTorrent::TorrentImpl::invokeAsync<BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)> >(BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::{lambda()#1}::operator()()::{lambda()#1}::operator()() const torrentimpl.cpp:2753
QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, BitTorrent::TorrentImpl::invokeAsync<BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)> >(BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::{lambda()#1}::operator()()::{lambda()#1}>::call(BitTorrent::TorrentImpl::invokeAsync<BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)> >(BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::{lambda()#1}::operator()()::{lambda()#1}&, void**) qobjectdefs_impl.h:146
QtPrivate::Functor<BitTorrent::TorrentImpl::invokeAsync<BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)> >(BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::{lambda()#1}::operator()()::{lambda()#1}, 0>::call<QtPrivate::List<>, void>(BitTorrent::TorrentImpl::invokeAsync<BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)> >(BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::{lambda()#1}::operator()()::{lambda()#1}&, void*, void**) qobjectdefs_impl.h:256
QtPrivate::QFunctorSlotObject<BitTorrent::TorrentImpl::invokeAsync<BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)> >(BitTorrent::TorrentImpl::fetchPeerInfo(std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::$_11, std::__1::function<void (QVector<BitTorrent::PeerInfo>)>) const::{lambda()#1}::operator()()::{lambda()#1}, 0, QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) qobjectdefs_impl.h:443
QMetaCallEvent::placeMetaCall(QObject*) 0x000007fed6d0429e
QObject::event(QEvent*) 0x000007fed6d05781
QApplicationPrivate::notify_helper(QObject*, QEvent*) 0x000007fed5cdc613
QApplication::notify(QObject*, QEvent*) 0x000007fed5cdd893
QCoreApplication::notifyInternal2(QObject*, QEvent*) 0x000007fed6cdd962
QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) 0x000007fed6cde7ad
QWindowsGuiEventDispatcher::sendPostedEvents() 0x000007fed7dc12fe
QEventDispatcherWin32::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) 0x000007fed6d31b8c
QWindowsGuiEventDispatcher::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) 0x000007fed7dc12e5
QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) 0x000007fed6cdabd6
QCoreApplication::exec() 0x000007fed6cddefd
Application::exec application.cpp:921
main main.cpp:261
__tmainCRTStartup 0x000000013f581316
WinMainCRTStartup 0x000000013f581156

Log(s) & preferences file(s)

No response

@glassez glassez self-assigned this Mar 22, 2023
@glassez glassez added the GUI GUI-related issues/changes label Mar 22, 2023
@glassez glassez added this to the 4.6.0 milestone Mar 22, 2023
@glassez
Copy link
Member

glassez commented Mar 22, 2023

2. Add two I2P torrents.

I'm noob in I2P. I installed i2pd and used one i2p torrent provided in a related Issue. Could you tell me about torrenting in i2p, i.e. how and where I could find torrents? Well, or at least provide me with a couple more torrents for better testing.

@Vort
Copy link
Contributor Author

Vort commented Mar 22, 2023

Could you tell me about torrenting in i2p

I don't know much about it too :)
I hope that people who use it will eventually come here, to GitHub.

how and where I could find torrents?

First of all, browser should be tuned to use localhost I2P proxy (HTTP or SOCKS) to be able to open .i2p websites.
Then open http://tracker2.postman.i2p/, find some popular torrents, and use magnet links from there.

Well, or at least provide me with a couple more torrents for better testing.

Second torrent I used for testing is this one:
magnet:?xt=urn:btih:b51676e4f60411406044faa69b098962040379b8&dn=I2P+Update+2.2.0&tr=http://tracker2.postman.i2p/announce.php

@glassez
Copy link
Member

glassez commented Mar 23, 2023

@Vort
Could you test #18748?

@Vort
Copy link
Contributor Author

Vort commented Mar 23, 2023

I assume such solution may be not perfect - it shows all connecting peers (without PeerID maybe?) as single line. Maybe IP:port can be mixed into hash?
However most likely it fixes this bug - I can't reproduce such crash anymore.

@glassez
Copy link
Member

glassez commented Mar 23, 2023

I assume such solution may be not perfect - it shows all connecting peers (without PeerID maybe?) as single line.

As stated in PR OP:

Index the peers by the same identifier as used in libtorrent

peer_id is used as unique identifier in libtorrent so there are no different peers with the same peer_id are connected to the same torrent at the same time.

@Vort
Copy link
Contributor Author

Vort commented Mar 23, 2023

Looks like there are moments when peer object already exists, but peer_id is not initialized yet.

@glassez
Copy link
Member

glassez commented Mar 23, 2023

Looks like there are moments when peer object already exists, but peer_id is not initialized yet.

Could you explain it in more detail? Or is it just your guess?

@Vort
Copy link
Contributor Author

Vort commented Mar 23, 2023

  1. I looked into library code and found no initialization of peer_id in constructor. Maybe I was looking not carefully enough, not sure.
  2. I compared behaviour of qBittorrent before Index peers by PeerID #18748 change and after it. Before I saw periodic addition of lots of "empty" peers to the list. After it I see only single empty peer. By empty I mean all zeroes (download, upload) and no client id. This is how it looks after the change:
    image

Such behaviour may be not fixable for I2P without solving identification/addresses problem.
But I expect problem with usage of peer_id to appear also for clearnet peers (did not tested, just guessing), and for them it should be possible to make better solution.

@glassez
Copy link
Member

glassez commented Mar 24, 2023

@Vort
How about #18753?

@Vort
Copy link
Contributor Author

Vort commented Mar 24, 2023

Now I see lots of peers and no crashes so far:
i2p_lots_of_peers
Looks like problem is solved. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Crash GUI GUI-related issues/changes
Projects
None yet
3 participants