Seite 1 von 1
[XAudio2] Deadlock
Verfasst: 20.09.2011, 21:34
von Krishty
Hi,
Das hier verursacht einen Deadlock in XAudio2, der – falls ich Glück habe – nach zehn Minuten mit einer Zugriffsverletzung endet. Zwei Internets für den, der mir sagen kann, was ich falsch mache. Bin scheinbar seit Tagen im Wald-vor-lauter-Bäumen-Modus.
Code: Alles auswählen
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
IXAudio2 * audio = nullptr;
XAudio2Create(&audio);
IXAudio2MasteringVoice * voice;
audio->CreateMasteringVoice(&voice);
// Hier scheint alles bestens; ich könnte sogar schön Source Voices erzeugen und damit Sounds abspielen, unterbrechen und blablah
voice->DestroyVoice(); // DEADLOCK
Falls ich im Debug-Modus arbeite, gibt es keine Meldungen außer
Unloaded 'C:\Windows\SysWOW64\avrt.dll'
The thread 'Win32 Thread' (0x1018) has exited with code 0 (0x0).
Gruß, Ky
Re: [XAudio2] Deadlock
Verfasst: 20.09.2011, 22:08
von eXile
Nope, Chuck Testa.
Leeres Projekt angelegt, Code so in die main gehauen, kein Deadlock. Auf x86 und x64, Debug und Release.
Re: [XAudio2] Deadlock
Verfasst: 21.09.2011, 20:36
von Krishty
Wtf. Im Release-Build geht
alles; selbst, wenn ich XAudio2 mit Debug-Features initialisiere.
Im Debug-Build geht nichts; egal, ob mit oder ohne Debug-Features und mit oder ohne IDE.
Debug-Symbole sagen während des Deadlocks:
Code: Alles auswählen
ntdll.dll!_ZwWaitForSingleObject@12() + 0x15 bytes
ntdll.dll!_ZwWaitForSingleObject@12() + 0x15 bytes
kernel32.dll!_WaitForSingleObjectExImplementation@12() + 0x43 bytes
MMDevAPI.dll!AXB::WaitForOperations() + 0x1504d bytes
MMDevAPI.dll!CMediaNotifications::UnregisterMediaCallback() + 0x78 bytes
MMDevAPI.dll!_UnregisterMediaCallback@4() + 0x25 bytes
AudioSes.dll!CAudioClient::FinalRelease() + 0x315 bytes
AudioSes.dll!ATL::CComObject<CAudioClient>::~CComObject<CAudioClient>() + 0x33 bytes
AudioSes.dll!ATL::CComObject<CAudioClient>::`vector deleting destructor'() + 0xd bytes
AudioSes.dll!ATL::CComObject<CAudioClient>::Release() + 0x27 bytes
XAudio2_7.dll!RELEASE<IAudioSessionControl>() + 0x1f bytes
XAudio2_7.dll!LEAPCORE::CEngineRendererConnection::~CEngineRendererConnection() + 0x91 bytes
XAudio2_7.dll!LEAPCORE::CEngineRendererConnection::`vector deleting destructor'() + 0x11 bytes
XAudio2_7.dll!CMemoryHelper::Delete<LEAPCORE::CRendererConnection>() + 0x35 bytes
XAudio2_7.dll!LEAPCORE::CLeapSystem::DisconnectRenderer() + 0x82 bytes
XAudio2_7.dll!XAUDIO2::CX2OutputVoice::Destroy() + 0xba bytes
XAudio2_7.dll!XAUDIO2::CX2Voice::DestroyVoice() + 0xf0 bytes
XAudio2_7.dll!XAUDIO2::CX2SourceVoice::DestroyVoice() + 0x11 bytes
> XXX.exe!main() Line 25 + 0x10 bytes C++
Re: [XAudio2] Deadlock
Verfasst: 21.09.2011, 21:48
von Krishty
Ich habe die Ursache:
Die Zeit, die XAudio2 zum Zerstören der Mastering Voice braucht, ist linear abhängig von der Menge reservierten Stapelspeichers. Wenn ich 1 GiB reserviere (/STACK:1073741824; die Einstellung hatte ich noch als Überbleibsel von meinen _alloca()-Experimenten), dauert die Zerstörung halt zehn Minuten. Bei einem MiB ist es kaum mehr spürbar.
Dieser Stapelspeicher ist zwar reserviert, wird aber zu keiner Zeit genutzt. Darum in aller Deutlichkeit:
WTF?!?
Mir ist klar, dass XAudio2 einen Thread für meine Mastering Voice erstellt, und der mit aller Wahrscheinlichkeit genauso viel Stapel zugesichert bekommt. Aber der wird ja auch nicht benutzt, sonst würde das im Task-Manager auftauchen. Warum beschäftigt sowas minutenlang WaitForSingleObject()? Was zur …?!?
Re: [XAudio2] Deadlock
Verfasst: 21.09.2011, 21:54
von dot
Vielleicht fehlt ihm der Adressraum!?
Re: [XAudio2] Deadlock
Verfasst: 21.09.2011, 21:55
von Krishty
Und das nur beim Runterfahren, vorher alles ruck-zuck?
Werden Seiten eigentlich beim Lesen comitted? Falls nicht, haben die bestimmt irgendeinen Debugging-Scheiß in der DLL vergessen und suchen den kompletten Stapel einmal von oben nach unten nach Magic Numbers ab oder so … Copy on Write?
Re: [XAudio2] Deadlock
Verfasst: 21.09.2011, 22:08
von dot
Ja, vermutlich ist irgendsowas. Schau mal ob er dir da nicht vielleicht anfängt wie wild zu swappen!?
Re: [XAudio2] Deadlock
Verfasst: 21.09.2011, 22:12
von Krishty
Keine Datenträgeraktivität, keine CPU-Auslastung, keine Seitenfehler, nichts. Er hängt einfach nur in WaitForSingleObject() irgendwo in den Annalen von XAudio2.
Ich muss auch das „linear“ zurücknehmen. Bis kurz vor 1 GB merkt man quasi nichts; bei 900.000.000 B sind es 2 s; bei 1.000.000.000 B schon 8 s; bei 1.073.741.824 zehn Minuten und 1.200.000.000 habe ich eben abgebrochen.
Es nervt auch, dass Visual C++ nach Ändern des Werts nicht neu linken will. Ich muss immer Rebuild’en, damit er übernommen wird …
Was habe ich nur wieder für ein Glück. Die absolut unscheinbarste Linker-Einstellung lässt einen API-Aufruf länger dauern, und auch nur, weil ich in einer Mixtur aus Zufall und Wahn eine Zahl der richtigen Größenordnung getroffen habe. Derweil funktionierte mein Programmtext, den ich die letzten vier Tage bis ins letzte Byte gedebuggt habe, natürlich seit jeher fehlerfrei.