Project

General

Profile

Actions

Emulator Issues #12889

open

Deadlock when opening Controllers after ending emulation

Added by JosJuice almost 2 years ago. Updated almost 2 years ago.

Status:
New
Priority:
Normal
Assignee:
-
% Done:

0%

Operating system:
N/A
Issue type:
Bug
Milestone:
Regression:
No
Relates to usability:
No
Relates to performance:
No
Easy:
No
Relates to maintainability:
No
Regression start:
Fixed in:

Description

Game Name?

Aggressive Inline

Game ID? (right click the game in the game list, Properties, Info tab)

GILP51

MD5 Hash? (right click the game in the game list, Properties, Verify tab, Verify Integrity button)

e7b3463eb2da28c476fc075192fa44a8

What's the problem? Describe what went wrong.

I got myself a deadlock recently. I'm opening this issue report mostly to have a good place to save the stack traces.

What steps will reproduce the problem?

  1. Exit GC emulation by clicking the close button of the emulation window
  2. Click the Controllers button right afterwards
  3. Hope you actually trigger it

Is the issue present in the latest development version? For future reference, please also write down the version number of the latest development version.

The issue happened in a version of PR 9624 which was based on 5.0-16285. I don't believe any of the changes in that PR are related to the issue.

Is the issue present in the latest stable version?

Not tested, since the problem isn't consistent. Chances are that it doesn't happen in 5.0 since 5.0 doesn't have the new config system.

Is there anything else that can help developers narrow down the issue? (e.g. logs, screenshots,
configuration files, savefiles, savestates)

Main Thread:

    [External Code] 
>   [Inline Frame] Dolphin.exe!std::shared_mutex::lock_shared() Line 52 C++
    [Inline Frame] Dolphin.exe!std::shared_lock<std::shared_mutex>::{ctor}(std::shared_mutex &) Line 241    C++
    Dolphin.exe!Config::GetLayer(Config::LayerType layer) Line 49   C++
    Dolphin.exe!Config::Get<bool>(Config::LayerType layer, const Config::Info<bool> & info) Line 53 C++
    Dolphin.exe!`ConfigLoaders::SaveToSYSCONF'::`8'::<lambda_1>::operator()<Config::Info<bool> const>(const Config::Info<bool> * info) Line 56  C++
    [Inline Frame] Dolphin.exe!std::invoke(ConfigLoaders::SaveToSYSCONF::__l8::<lambda_1> &&) Line 1490 C++
    [Inline Frame] Dolphin.exe!std::_Variant_dispatcher<std::integer_sequence<unsigned __int64,2>>::_Dispatch2(ConfigLoaders::SaveToSYSCONF::__l8::<lambda_1> &&) Line 1480 C++
    [Inline Frame] Dolphin.exe!std::_Visit_strategy<1>::_Visit2(unsigned __int64) Line 1586 C++
    [Inline Frame] Dolphin.exe!std::_Visit_impl(ConfigLoaders::SaveToSYSCONF::__l8::<lambda_1> &&) Line 1640    C++
    [Inline Frame] Dolphin.exe!std::visit(ConfigLoaders::SaveToSYSCONF::__l8::<lambda_1> &&) Line 1658  C++
    Dolphin.exe!ConfigLoaders::SaveToSYSCONF(Config::LayerType layer, std::function<bool __cdecl(Config::Location const &)> predicate) Line 43  C++
    Dolphin.exe!ConfigLoaders::BaseConfigLayerLoader::Save(Config::Layer * layer) Line 143  C++
    Dolphin.exe!Config::Layer::Save() Line 94   C++
    Dolphin.exe!Config::Save() Line 124 C++
    [Inline Frame] Dolphin.exe!WiimoteControllersWidget::OnWiimoteModeChanged() Line 194    C++
    [Inline Frame] Dolphin.exe!WiimoteControllersWidget::LoadSettings() Line 321    C++
    Dolphin.exe!WiimoteControllersWidget::WiimoteControllersWidget(QWidget * parent) Line 42    C++
    Dolphin.exe!ControllersWindow::ControllersWindow(QWidget * parent) Line 20  C++
    Dolphin.exe!MainWindow::ShowControllersWindow() Line 1161   C++
    [External Code] 
    Dolphin.exe!app_main(int argc, char * * argv) Line 284  C++
    Dolphin.exe!wWinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, wchar_t * __formal, int __formal) Line 303 C++
    [External Code] 

CPU-GPU thread:

    [External Code] 
>   [Inline Frame] Dolphin.exe!std::shared_mutex::lock() Line 40    C++
    [Inline Frame] Dolphin.exe!std::unique_lock<std::shared_mutex>::{ctor}(std::shared_mutex &) Line 133    C++
    Dolphin.exe!Config::ClearCurrentRunLayer() Line 146 C++
    Dolphin.exe!BootManager::RestoreConfig() Line 222   C++
    Dolphin.exe!`Core::EmuThread'::`2'::<lambda_3>::operator()() Line 562   C++
    [Inline Frame] Dolphin.exe!Common::ScopeGuard<`Core::EmuThread'::`2'::<lambda_3>>::Exit() Line 27   C++
    [Inline Frame] Dolphin.exe!Common::ScopeGuard<`Core::EmuThread'::`2'::<lambda_3>>::{dtor}() Line 21 C++
    Dolphin.exe!Core::EmuThread(std::unique_ptr<BootParameters,std::default_delete<BootParameters>> boot, WindowSystemInfo wsi) Line 678    C++
    [External Code] 

DiscordHandler:

    [External Code] 
    [Inline Frame] Dolphin.exe!std::shared_mutex::lock_shared() Line 52 C++
    [Inline Frame] Dolphin.exe!std::shared_lock<std::shared_mutex>::{ctor}(std::shared_mutex &) Line 241    C++
>   Dolphin.exe!Config::GetAsString(const Config::Location & config) Line 214   C++
    [Inline Frame] Dolphin.exe!Config::GetUncached(const Config::Info<bool> &) Line 76  C++
    Dolphin.exe!Config::Get<bool>(const Config::Info<bool> & info) Line 64  C++
    Dolphin.exe!Discord::CallPendingCallbacks() Line 201    C++
    Dolphin.exe!DiscordHandler::Run() Line 79   C++
    [External Code] 
Actions #1

Updated by AdmiralCurtiss almost 2 years ago

Wait, how does this ever work? If I'm reading this right, this is just the Main Thread locking itself. Config::Save() acquires and keeps the s_layers_rw_lock locked (on the shared side), then SaveToSYSCONF() calls Config::Get() which tries to re-acquire the same lock on the same side.

Actions #2

Updated by AdmiralCurtiss almost 2 years ago

(which it can't, since shared mutexes aren't recursive)

Actions #3

Updated by AdmiralCurtiss almost 2 years ago

So I'm still not sure what actually triggers this, but I realized that we could probably make this mutex pseudo-recursive by using a thread_local flag that indicates whether we hold the lock. Y'know, if we want to...

Actions

Also available in: Atom PDF