kcat / openal-soft

OpenAL Soft is a software implementation of the OpenAL 3D audio API.
Other
2.19k stars 531 forks source link

Potential memory leak in CS:GO #125

Closed guihkx closed 7 years ago

guihkx commented 7 years ago

I've opened a ticket in the CS:GO repo a few days ago (ValveSoftware/csgo-osx-linux#1438) regarding a very high memory usage in CS:GO. Today, @Wurzelsim suggested me to downgrade the openal/lib32-openal packages back to version 1.17.2 and it fixed the memory issue. Here's the log of running CS:GO with ALSOFT_LOGLEVEL=3:

AL lib: (II) alc_initconfig: Initializing library v1.18.0-61e43d40 makepkg
AL lib: (II) alc_initconfig: Supported backends: jack, pulse, alsa, oss, port, null, wave
AL lib: (II) ReadALConfig: Loading config /etc/openal/alsoft.conf...
AL lib: (II) ReadALConfig: Loading config /etc/xdg/alsoft.conf...
AL lib: (II) ReadALConfig: Loading config /home/gui/.alsoftrc...
AL lib: (II) ReadALConfig: Loading config /home/gui/.config/alsoft.conf...
AL lib: (II) GetProcPath: Got: /home/gui/.local/share/Steam/steamapps/common/Counter-Strike Global Offensive
AL lib: (II) ReadALConfig: Loading config /home/gui/.local/share/Steam/steamapps/common/Counter-Strike Global Offensive/alsoft.conf...
AL lib: (II) GetConfigValue: Key disable-cpu-exts not found
AL lib: (II) FillCPUCaps: Detected max CPUID function: 0xd (ext. 0x80000008)
AL lib: (II) FillCPUCaps: Vendor ID: ""
AL lib: (II) FillCPUCaps: Name: "       Intel(R) Core(TM) i5-3570K CPU @ 3.40GHz"
AL lib: (II) FillCPUCaps: Extensions: +SSE +SSE2 +SSE3 +SSE4.1
AL lib: (II) GetConfigValue: Key rt-prio not found
AL lib: (II) GetConfigValue: Key resampler not found
AL lib: (II) GetConfigValue: Key trap-al-error not found
AL lib: (II) GetConfigValue: Key trap-alc-error not found
AL lib: (II) GetConfigValue: Key reverb/boost not found
AL lib: (II) GetConfigValue: Key reverb/emulate-eax not found
AL lib: (II) GetConfigValue: Key drivers not found
AL lib: (II) GetConfigValue: Key jack/spawn-server not found
AL lib: (WW) jack_msg_handler: connect(2) call to /dev/shm/jack-1000/default/jack_0 failed (err=No such file or directory)
AL lib: (WW) jack_msg_handler: attempt to connect to server failed
AL lib: (WW) ALCjackBackendFactory_init: jack_client_open() failed, 0x11
AL lib: (WW) alc_initconfig: Failed to initialize backend "jack"
AL lib: (II) GetConfigValue: Key pulse/spawn-server not found
AL lib: (II) alc_initconfig: Initialized backend "pulse"
AL lib: (II) alc_initconfig: Added "pulse" for playback
AL lib: (II) alc_initconfig: Added "pulse" for capture
AL lib: (II) GetConfigValue: Key excludefx not found
AL lib: (II) GetConfigValue: Key default-reverb not found
AL lib: (II) GetConfigValue: Key channels not found
AL lib: (II) GetConfigValue: Key sample-type not found
AL lib: (II) GetConfigValue: Key frequency not found
AL lib: (II) GetConfigValue: Key periods not found
AL lib: (II) GetConfigValue: Key period_size not found
AL lib: (II) GetConfigValue: Key sources not found
AL lib: (II) GetConfigValue: Key slots not found
AL lib: (II) GetConfigValue: Key sends not found
AL lib: (II) GetConfigValue: Key pulse/allow-moves not found
AL lib: (II) ALCpulsePlayback_open: Connecting to "(default)"
AL lib: (II) GetConfigValue: Key ambi-format not found
AL lib: (II) GetConfigValue: Key dither not found
AL lib: (II) alcOpenDevice: Created device 0x20418000, "Built-in Audio Analog Stereo"
AL lib: (II) GetConfigValue: Key hrtf not found
AL lib: (II) UpdateDeviceParams: Pre-reset: Stereo, Float, 44100hz, 1024 update size x3
AL lib: (II) ALCpulsePlayback_sinkInfoCallback: Active port: analog-output-headphones (Headphones)
AL lib: (II) GetConfigValue: Key pulse/fix-rate not found
AL lib: (II) GetConfigValue: Key pulse/allow-moves not found
AL lib: (II) ALCpulsePlayback_bufferAttrCallback: minreq=8192, tlength=25296, prebuf=0
AL lib: (II) UpdateDeviceParams: Post-reset: Stereo, Float, 96000hz, 1024 update size x7
AL lib: (II) GetConfigValue: Key stereo-mode not found
AL lib: (II) GetConfigValue: Key hrtf-paths not found
AL lib: (II) GetConfigValue: Key hrtf_tables not found
AL lib: (II) DirectorySearch: Searching /home/gui/.local/share/Steam/steamapps/common/Counter-Strike Global Offensive for *.mhr
AL lib: (II) DirectorySearch: Searching /home/gui/.local/share/openal/hrtf for *.mhr
AL lib: (II) DirectorySearch: Searching /usr/local/share/openal/hrtf for *.mhr
AL lib: (II) DirectorySearch: Searching /usr/share/openal/hrtf for *.mhr
AL lib: (II) DirectorySearch: Got result /usr/share/openal/hrtf/default-44100.mhr
AL lib: (II) DirectorySearch: Got result /usr/share/openal/hrtf/default-48000.mhr
AL lib: (II) AddFileEntry: Got new file "/usr/share/openal/hrtf/default-44100.mhr"
AL lib: (II) AddFileEntry: Adding entry "default-44100" from file "/usr/share/openal/hrtf/default-44100.mhr"
AL lib: (II) AddFileEntry: Got new file "/usr/share/openal/hrtf/default-48000.mhr"
AL lib: (II) AddFileEntry: Adding entry "default-48000" from file "/usr/share/openal/hrtf/default-48000.mhr"
AL lib: (II) GetConfigValue: Key default-hrtf not found
AL lib: (II) GetLoadedHrtf: Loading /usr/share/openal/hrtf/default-44100.mhr...
AL lib: (II) GetLoadedHrtf: Detected data set format v1
AL lib: (II) GetLoadedHrtf: Loaded HRTF support for format: Stereo 44100hz
AL lib: (II) Hrtf_DecRef: Unloaded unused HRTF /usr/share/openal/hrtf/default-44100.mhr
AL lib: (II) GetLoadedHrtf: Loading /usr/share/openal/hrtf/default-48000.mhr...
AL lib: (II) GetLoadedHrtf: Detected data set format v1
AL lib: (II) GetLoadedHrtf: Loaded HRTF support for format: Stereo 48000hz
AL lib: (II) Hrtf_DecRef: Unloaded unused HRTF /usr/share/openal/hrtf/default-48000.mhr
AL lib: (II) aluInitRenderer: HRTF disabled
AL lib: (II) GetConfigValue: Key cf_level not found
AL lib: (II) aluInitRenderer: BS2B enabled
AL lib: (II) UpdateDeviceParams: Channel config, Dry: 2, FOA: 0, Real: 0
AL lib: (II) UpdateDeviceParams: Allocating 2 channels, 16384 bytes
AL lib: (II) UpdateDeviceParams: Max sources: 256 (255 + 1), effect slots: 64, sends: 2
AL lib: (II) GetConfigValue: Key output-limiter not found
AL lib: (II) UpdateDeviceParams: Output limiter enabled
AL lib: (II) GetConfigValue: Key volume-adjust not found
AL lib: (II) alcCreateContext: Created context 0x1f0a0700
AL lib: (WW) alcSetError: Error generated on device (nil), code 0xa001
****loading serverbrowser_client.so
/home/gui/.local/share/Steam/steamapps/common/Counter-Strike Global Offensive/csgo.sh: line 64:  3285 Killed                  ${DEBUGGER} "${GAMEROOT}"/${GAMEEXE} "$@"

I had to kill the CS:GO process manually, otherwise it would freeze my entire system.

Here's some information about my system taken from the Steam client. Please let me know if you need any other information. Thank you!

kcat commented 7 years ago

Are you able to build OpenAL Soft from source yourself? If so, doing a git bisect between 1.17.2 and 1.18.0 would help narrow the issue down to a specific commit, which will hopefully shed light on what the issue might be.

Otherwise, if you're able to run the game for as long as you can and quit normally before it dies, a full trace log would help to see if there's any buffers or anything being leaked.

guihkx commented 7 years ago
1f64f9d016790797ecd81e00f0392b34abdddcb6 is the first bad commit
commit 1f64f9d016790797ecd81e00f0392b34abdddcb6
Author: Chris Robinson <chris.kcat@gmail.com>
Date:   Sat Apr 8 10:01:04 2017 -0700

    Try to write the full configured buffer length with PulseAudio

    This basically ignores tlength even if it's smaller than what was requested. It
    keeps up-to-date with minreq changes too now, in case that happens.
guihkx commented 7 years ago

I really tried to keep CS:GO running for a longer time, but it's impossible to exit CS:GO cleanly, I'll always run out of memory unless I SIGKILL CS:GO... Please let me know if I should try something else. This is really the best I can do right now:

AL lib: (II) alc_initconfig: Initializing library v1.18.0-61e43d40 makepkg
AL lib: (II) alc_initconfig: Supported backends: jack, pulse, alsa, oss, port, null, wave
AL lib: (II) ReadALConfig: Loading config /etc/openal/alsoft.conf...
AL lib: (II) ReadALConfig: Loading config /etc/xdg/alsoft.conf...
AL lib: (II) ReadALConfig: Loading config /home/gui/.alsoftrc...
AL lib: (II) ReadALConfig: Loading config /home/gui/.config/alsoft.conf...
AL lib: (II) GetProcPath: Got: /home/gui/.local/share/Steam/steamapps/common/Counter-Strike Global Offensive
AL lib: (II) ReadALConfig: Loading config /home/gui/.local/share/Steam/steamapps/common/Counter-Strike Global Offensive/alsoft.conf...
AL lib: (II) GetConfigValue: Key disable-cpu-exts not found
AL lib: (II) FillCPUCaps: Detected max CPUID function: 0xd (ext. 0x80000008)
AL lib: (II) FillCPUCaps: Vendor ID: ""
AL lib: (II) FillCPUCaps: Name: "       Intel(R) Core(TM) i5-3570K CPU @ 3.40GHz"
AL lib: (II) FillCPUCaps: Extensions: +SSE +SSE2 +SSE3 +SSE4.1
AL lib: (II) GetConfigValue: Key rt-prio not found
AL lib: (II) GetConfigValue: Key resampler not found
AL lib: (II) GetConfigValue: Key trap-al-error not found
AL lib: (II) GetConfigValue: Key trap-alc-error not found
AL lib: (II) GetConfigValue: Key reverb/boost not found
AL lib: (II) GetConfigValue: Key reverb/emulate-eax not found
AL lib: (II) GetConfigValue: Key drivers not found
AL lib: (II) GetConfigValue: Key jack/spawn-server not found
AL lib: (WW) jack_msg_handler: connect(2) call to /dev/shm/jack-1000/default/jack_0 failed (err=No such file or directory)
AL lib: (WW) jack_msg_handler: attempt to connect to server failed
AL lib: (WW) ALCjackBackendFactory_init: jack_client_open() failed, 0x11
AL lib: (WW) alc_initconfig: Failed to initialize backend "jack"
AL lib: (II) GetConfigValue: Key pulse/spawn-server not found
AL lib: (II) alc_initconfig: Initialized backend "pulse"
AL lib: (II) alc_initconfig: Added "pulse" for playback
AL lib: (II) alc_initconfig: Added "pulse" for capture
AL lib: (II) GetConfigValue: Key excludefx not found
AL lib: (II) GetConfigValue: Key default-reverb not found
AL lib: (II) GetConfigValue: Key channels not found
AL lib: (II) GetConfigValue: Key sample-type not found
AL lib: (II) GetConfigValue: Key frequency not found
AL lib: (II) GetConfigValue: Key periods not found
AL lib: (II) GetConfigValue: Key period_size not found
AL lib: (II) GetConfigValue: Key sources not found
AL lib: (II) GetConfigValue: Key slots not found
AL lib: (II) GetConfigValue: Key sends not found
AL lib: (II) GetConfigValue: Key pulse/allow-moves not found
AL lib: (II) ALCpulsePlayback_open: Connecting to "(default)"
AL lib: (II) GetConfigValue: Key ambi-format not found
AL lib: (II) GetConfigValue: Key dither not found
AL lib: (II) alcOpenDevice: Created device 0x23ec8000, "Built-in Audio Analog Stereo"
AL lib: (II) GetConfigValue: Key hrtf not found
AL lib: (II) UpdateDeviceParams: Pre-reset: Stereo, Float, 44100hz, 1024 update size x3
AL lib: (II) ALCpulsePlayback_sinkInfoCallback: Active port: analog-output-headphones (Headphones)
AL lib: (II) GetConfigValue: Key pulse/fix-rate not found
AL lib: (II) GetConfigValue: Key pulse/allow-moves not found
AL lib: (II) ALCpulsePlayback_bufferAttrCallback: minreq=8192, tlength=36864, prebuf=0
AL lib: (II) UpdateDeviceParams: Post-reset: Stereo, Float, 96000hz, 1024 update size x7
AL lib: (II) GetConfigValue: Key stereo-mode not found
AL lib: (II) GetConfigValue: Key hrtf-paths not found
AL lib: (II) GetConfigValue: Key hrtf_tables not found
AL lib: (II) ALCpulsePlayback_bufferAttrCallback: minreq=8192, tlength=25296, prebuf=0
AL lib: (II) DirectorySearch: Searching /home/gui/.local/share/Steam/steamapps/common/Counter-Strike Global Offensive for *.mhr
AL lib: (II) DirectorySearch: Searching /home/gui/.local/share/openal/hrtf for *.mhr
AL lib: (II) DirectorySearch: Searching /usr/local/share/openal/hrtf for *.mhr
AL lib: (II) DirectorySearch: Searching /usr/share/openal/hrtf for *.mhr
AL lib: (II) DirectorySearch: Got result /usr/share/openal/hrtf/default-44100.mhr
AL lib: (II) DirectorySearch: Got result /usr/share/openal/hrtf/default-48000.mhr
AL lib: (II) AddFileEntry: Got new file "/usr/share/openal/hrtf/default-44100.mhr"
AL lib: (II) AddFileEntry: Adding entry "default-44100" from file "/usr/share/openal/hrtf/default-44100.mhr"
AL lib: (II) AddFileEntry: Got new file "/usr/share/openal/hrtf/default-48000.mhr"
AL lib: (II) AddFileEntry: Adding entry "default-48000" from file "/usr/share/openal/hrtf/default-48000.mhr"
AL lib: (II) GetConfigValue: Key default-hrtf not found
AL lib: (II) GetLoadedHrtf: Loading /usr/share/openal/hrtf/default-44100.mhr...
AL lib: (II) GetLoadedHrtf: Detected data set format v1
AL lib: (II) GetLoadedHrtf: Loaded HRTF support for format: Stereo 44100hz
AL lib: (II) Hrtf_DecRef: Unloaded unused HRTF /usr/share/openal/hrtf/default-44100.mhr
AL lib: (II) GetLoadedHrtf: Loading /usr/share/openal/hrtf/default-48000.mhr...
AL lib: (II) GetLoadedHrtf: Detected data set format v1
AL lib: (II) GetLoadedHrtf: Loaded HRTF support for format: Stereo 48000hz
AL lib: (II) Hrtf_DecRef: Unloaded unused HRTF /usr/share/openal/hrtf/default-48000.mhr
AL lib: (II) aluInitRenderer: HRTF disabled
AL lib: (II) GetConfigValue: Key cf_level not found
AL lib: (II) aluInitRenderer: BS2B enabled
AL lib: (II) UpdateDeviceParams: Channel config, Dry: 2, FOA: 0, Real: 0
AL lib: (II) UpdateDeviceParams: Allocating 2 channels, 16384 bytes
AL lib: (II) UpdateDeviceParams: Max sources: 256 (255 + 1), effect slots: 64, sends: 2
AL lib: (II) GetConfigValue: Key output-limiter not found
AL lib: (II) UpdateDeviceParams: Output limiter enabled
AL lib: (II) GetConfigValue: Key volume-adjust not found
AL lib: (II) alcCreateContext: Created context 0x22b7c540
AL lib: (WW) alcSetError: Error generated on device (nil), code 0xa001
AL lib: (WW) alcSetError: Error generated on device (nil), code 0xa001
AL lib: (WW) alcSetError: Error generated on device (nil), code 0xa001
AL lib: (WW) alGetError: Querying error state on null context (implicitly 0xa004)
Not enough memory
kcat commented 7 years ago

I see what the problem is. There's an error in the logic causing the mixer to think there was always some writable space, and PulseAudio never limited the amount of audio that could be buffered so it just kept allocating more and more until OOM.

The bug would occur when PulseAudio gives a much smaller tlength value than was requested (at least one period/minreq less). That happens here because the desired default 44.1khz sample rate is changed to 96khz to match the server, which in turn scales up the buffer metrics so it still roughly matches the original buffer latency. For whatever reason, PulseAudio gives back 25296 bytes for the stream's buffer, even though OpenAL Soft asked for 57344 bytes, which triggers the faulty logic.

Unfortunately the only way to fix this is to obey tlength, which means a higher risk of underruns when given back less than requested, or more latency when given back more than requested.

kcat commented 7 years ago

Can you check to see if it's fixed now with commit d4f3490a880f779f460332689a396ade69840f50?

guihkx commented 7 years ago

Yup, it's working again. Thank you!

I have to say that I know absolutely nothing about audio, and the fact that I'm using 96kHz is because I was having issues with my microphone, then I came across this article suggesting that I would have to change the default-sample-rate in /etc/pulse/daemon.conf accordingly, in order to remove the microphone noise. It didn't work for me, but I forgot to set it back to 48kHz...

spychodelics commented 7 years ago

thanks, downgrade on arch linux fixed the issue!