WineHQ

Wine and Valgrind: Difference between revisions

No edit summary
(removed links to patches that no longer apply, updated links)
 
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[http://www.valgrind.org/ Valgrind] is a set of tools aimed at finding bugs and performance problems in programs. By default, it catches reads of uninitialized memory, accesses to inaccessible memory, and memory leaks. It's useful for debugging wine itself, as well as windows apps running on Wine.
[https://www.valgrind.org/ Valgrind] is a set of tools aimed at finding bugs and performance problems in programs. By default, it catches reads of uninitialized memory, accesses to inaccessible memory, and memory leaks. It's useful for debugging wine itself, as well as windows apps running on Wine.


*You need Valgrind 3.8.0 or newer to avoid [https://bugs.kde.org/show_bug.cgi?id=275673 Valgrind Bug #275673] (v3.8 was released in late summer 2012, but just in case there are still a few people that haven't upgraded).
*To get the full power of Valgrind while debugging Wine, you need to build Wine from source '''after''' installing Valgrind. You'll also want to switch off certain compiler optimizations; the [[Building Wine#Developer Tools|Developer Tools]] section of the [[Building Wine]] page has more details.
 
*To get the full power of Valgrind while debugging Wine, you need to build Wine from source '''after''' installing Valgrind. You'll also want to switch off certain compiler optimizations; the "developer tools" section of the BuildingWine page has more details.


*Valgrind will work on [[macOS]] (starting with partial support in macOS v10.8 "Mountain Lion"). If you want line numbers with Valgrind on Mac, don't forget to tell Xcode to generate a .dSYM file, though you can also use gdb after the fact to look up line numbers.
*Valgrind will work on [[macOS]] (starting with partial support in macOS v10.8 "Mountain Lion"). If you want line numbers with Valgrind on Mac, don't forget to tell Xcode to generate a .dSYM file, though you can also use gdb after the fact to look up line numbers.


*In applications built with the debug version of the MS Visual C/C++ runtime, memory allocated via malloc() is always initialized. This obscures any uninitialized memory accesses that would normally appear from Valgrind (see ''[http://msdn.microsoft.com/en-us/library/bebs9zyz%28v=VS.80%29.aspx Memory Management and the Debug Heap]'' at MSDN for the full story).
*In applications built with the debug version of the MS Visual C/C++ runtime, memory allocated via malloc() is always initialized. This obscures any uninitialized memory accesses that would normally appear from Valgrind (see ''[https://web.archive.org/web/20100929150511/http://msdn.microsoft.com/en-us/library/bebs9zyz(VS.80).aspx Memory Management and the Debug Heap]'' at MSDN for the full story).




Line 13: Line 11:
To analyze a program running on Wine with Valgrind, just call valgrind with the appropriate options in front of the normal wine command. For example:
To analyze a program running on Wine with Valgrind, just call valgrind with the appropriate options in front of the normal wine command. For example:


  valgrind --trace-children=yes --vex-iropt-register-updates=allregs-at-mem-access --workaround-gcc296-bugs=yes wine foo.exe
  valgrind --trace-children=yes --vex-iropt-register-updates=allregs-at-mem-access wine foo.exe




Line 22: Line 20:
=== Valgrind Options Relevant for Wine ===
=== Valgrind Options Relevant for Wine ===
Over the years, several Valgrind options have turned out to be necessary, or at least very helpful, when analyzing Wine. Two in particular are necessary for Wine to function well under Valgrind:
Over the years, several Valgrind options have turned out to be necessary, or at least very helpful, when analyzing Wine. Two in particular are necessary for Wine to function well under Valgrind:
* ''[http://valgrind.org/docs/manual/manual-core.html#opt.trace-children --trace-children=yes]'' is necessary because wine starts new processes for individual programs
* ''[https://valgrind.org/docs/manual/manual-core.html#opt.trace-children --trace-children=yes]'' is necessary because wine starts new processes for individual programs
* ''[http://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver-limitations --vex-iropt-register-updates=allregs-at-mem-access]'' ensures that bitmap-related code, such as ''[https://source.winehq.org/WineAPI/GetBitmapBits.html GetBitmapBits()]'', works under Valgrind
* ''[https://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver-limitations --vex-iropt-register-updates=allregs-at-mem-access]'' ensures that bitmap-related code, such as ''[https://source.winehq.org/WineAPI/GetBitmapBits.html GetBitmapBits()]'', works under Valgrind


Several more are useful for suppressing known bugs or exceptions in Wine:
Several more are useful for suppressing known bugs or exceptions in Wine:
* ''[http://valgrind.org/docs/manual/mc-manual.html#opt.workaround-gcc296-bugs --workaround-gcc296-bugs=yes]'' quiets warnings about accesses slightly below the stack pointer. This is due to a known but benign piece of code in Wine's ''ntdll'' (see [http://bugs.winehq.org/show_bug.cgi?id=26263 Bug #26263] for details)
* ''[https://valgrind.org/docs/manual/manual-core.html#manual-core.suppress --suppressions=path/to/suppression-file]'' lets you pass a file with custom suppression rules to Valgrind. [[User:Austin987|Austin English]] maintains a collection of suppression files for Wine at his [https://github.com/austin987/wine_misc/tree/master/valgrind github repo]
* ''[http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress --suppressions=path/to/suppression-file]'' lets you pass a file with custom suppression rules to Valgrind. [[User:Austin987|Austin English]] maintains a collection of suppression files for Wine at his [https://github.com/austin987/wine_misc/tree/master/valgrind github repo]
This option can be repeated with multiple files
This option can be repeated with multiple files
* ''[http://valgrind.org/docs/manual/mc-manual.html#opt.partial-loads-ok --partial-loads-ok=yes]'' silences warnings for when bit-alignments overlap both addressable and illegal ranges. In particular, try this if the last three bytes of allocations throw a lot of "Invalid Read of Size N" warnings.
* ''[https://valgrind.org/docs/manual/mc-manual.html#opt.partial-loads-ok --partial-loads-ok=yes]'' silences warnings for when bit-alignments overlap both addressable and illegal ranges. In particular, try this if the last three bytes of allocations throw a lot of "Invalid Read of Size N" warnings.




There's a good chance these are false positives from vectorized string operations ([https://bugs.kde.org/show_bug.cgi?id=264936 Valgrind Bug Report #264936] has more info). In the Valgrind bug report, someone also mentions using GCC with the ''-fno-builtin-strdup'' compiler option to make the warnings disappear. It hasn't been tested with Wine, but the "Compiler Optimizations" section of [[Building Wine]] has more details about changing compiler flags while building Wine.
There's a good chance these are false positives from vectorized string operations ([https://bugs.kde.org/show_bug.cgi?id=264936 Valgrind Bug Report #264936] has more info). In the Valgrind bug report, someone also mentions using GCC with the ''-fno-builtin-strdup'' compiler option to make the warnings disappear. It hasn't been tested with Wine, but the [[Building Wine#Compiler Optimizations & Call-Stacks|Compiler Optimizations]] section of [[Building Wine]] has more details about changing compiler flags while building Wine.


=== Controlling Memory Leak Reports ===
=== Controlling Memory Leak Reports ===
There are a few more Valgrind options that let you fine-tune how much it reports about memory leaks. By default, Valgrind only gives a count of memory leaks detected at the end of execution.  
There are a few more Valgrind options that let you fine-tune how much it reports about memory leaks. By default, Valgrind only gives a count of memory leaks detected at the end of execution.  


To get more info, you want to pass the ''[http://valgrind.org/docs/manual/mc-manual.html#opt.leak-check --leak-check=full]'' flag when running Valgrind. This will give you individual reports about certain types of memory leaks (but not all). Once this option is set, you can use several other options to specify which kinds of memory leaks you want detailed reports for:
To get more info, you want to pass the ''[https://valgrind.org/docs/manual/mc-manual.html#opt.leak-check --leak-check=full]'' flag when running Valgrind. This will give you individual reports about certain types of memory leaks (but not all). Once this option is set, you can use several other options to specify which kinds of memory leaks you want detailed reports for:
* ''[http://valgrind.org/docs/manual/mc-manual.html#opt.show-leak-kinds --show-leak-kinds=definite,possible]'' only reports unfreed blocks with no pointers or that depend on interior pointers (the default)
* ''[https://valgrind.org/docs/manual/mc-manual.html#opt.show-leak-kinds --show-leak-kinds=definite,possible]'' only reports unfreed blocks with no pointers or that depend on interior pointers (the default)
* ''[http://valgrind.org/docs/manual/mc-manual.html#opt.show-reachable --show-possibly-lost=no]'' or ''[http://valgrind.org/docs/manual/mc-manual.html#opt.show-leak-kinds --show-leak-kinds=definite]'' only reports unfreed blocks with no pointers
* ''[https://valgrind.org/docs/manual/mc-manual.html#opt.show-reachable --show-possibly-lost=no]'' or ''[https://valgrind.org/docs/manual/mc-manual.html#opt.show-leak-kinds --show-leak-kinds=definite]'' only reports unfreed blocks with no pointers
* ''[http://valgrind.org/docs/manual/mc-manual.html#opt.show-reachable --show-reachable=yes]'' or ''[http://valgrind.org/docs/manual/mc-manual.html#opt.show-leak-kinds --show-leak-kinds=all]'' reports all forms of unfreed blocks, even trivial ones with clear pointers
* ''[https://valgrind.org/docs/manual/mc-manual.html#opt.show-reachable --show-reachable=yes]'' or ''[https://valgrind.org/docs/manual/mc-manual.html#opt.show-leak-kinds --show-leak-kinds=all]'' reports all forms of unfreed blocks, even trivial ones with clear pointers




Finally, by passing the ''[http://valgrind.org/docs/manual/mc-manual.html#opt.track-origins --track-origins=yes]'' option, you can ask Valgrind to give you stack backtraces to the point where a leaky memory block was allocated. This is terrifically helpful for debugging, but it has the downside of making valgrind run even slower.
Finally, by passing the ''[https://valgrind.org/docs/manual/mc-manual.html#opt.track-origins --track-origins=yes]'' option, you can ask Valgrind to give you stack backtraces to the point where a leaky memory block was allocated. This is terrifically helpful for debugging, but it has the downside of making valgrind run even slower.


== Conformance Tests under Valgrind ==
== Conformance Tests under Valgrind ==
To run Wine's ConformanceTests under Valgrind, you mainly need to set the ''WINETEST_WRAPPER'' and ''VALGRIND_OPTS'' variables, e.g...
To run Wine's ConformanceTests under Valgrind, you mainly need to set the ''WINETEST_WRAPPER'' and ''VALGRIND_OPTS'' variables, e.g...
<pre>
<pre>
export VALGRIND_OPTS="--trace-children=yes --track-origins=yes --gen-suppressions=all --suppressions=$HOME/valgrind-suppressions-ignore --suppressions=$HOME/valgrind-suppressions-external --num-callers=20 --workaround-gcc296-bugs=yes --vex-iropt-register-updates=allregs-at-mem-access"
export VALGRIND_OPTS="--trace-children=yes --track-origins=yes --gen-suppressions=all --suppressions=$HOME/valgrind-suppressions-ignore --suppressions=$HOME/valgrind-suppressions-external --num-callers=20 --vex-iropt-register-updates=allregs-at-mem-access"
WINETEST_WRAPPER=valgrind make -k test > test.log 2>&1
WINETEST_WRAPPER=valgrind make -k test > test.log 2>&1
</pre>
</pre>
Line 59: Line 56:
* ''MAX_FREE_PENDING'' controls how long freed blocks are kept out of circulation and is set to 1024 by default. If you think your app is hanging on to freed pointers longer than it should, increasing it and recompiling wine might help Valgrind detect use-after-free errors.
* ''MAX_FREE_PENDING'' controls how long freed blocks are kept out of circulation and is set to 1024 by default. If you think your app is hanging on to freed pointers longer than it should, increasing it and recompiling wine might help Valgrind detect use-after-free errors.
* ''HEAP_TAIL_EXTRA_SIZE'' gives the size of the redzone at the end of each block.  If your app nests really big structs within another struct or array, you might need to increase this to catch overrun errors. Watch out though because increasing it beyond 32 or so bytes can cause strange false positives sometimes.
* ''HEAP_TAIL_EXTRA_SIZE'' gives the size of the redzone at the end of each block.  If your app nests really big structs within another struct or array, you might need to increase this to catch overrun errors. Watch out though because increasing it beyond 32 or so bytes can cause strange false positives sometimes.
=== Additional Wine patches ===
There are also a few patches that have accumulated on Bugzilla over the years to make Wine play better with Valgrind. You might be able to get some use out of them for debugging (or even refine them and help get them accepted into the wine master branch):
* Clear slots in new argv[] ([https://bugs.winehq.org/show_bug.cgi?id=14359 Bug #14359])
* Co-operate with valgrind at execv ([https://bugs.winehq.org/show_bug.cgi?id=14361 Bug #14361])
* Enhance loader and wine_main_preload_info for valgrind ([https://bugs.winehq.org/show_bug.cgi?id=14364 Bug #14364])
* Do not touch high address space (initial stack, user_space_limit) ([https://bugs.winehq.org/show_bug.cgi?id=14365 Bug #14365])
* Co-operate with valgrind when switching stacks ([https://bugs.winehq.org/show_bug.cgi?id=14366 Bug #14366])
* Adjust timeout interval for virtulaizers ([https://bugs.winehq.org/show_bug.cgi?id=14370 Bug #14370])


== Valgrind Bugs / Feature Requests ==
== Valgrind Bugs / Feature Requests ==
There are several open bugs/feature requests in Valgrind that affect / would benefit Wine (roughly descending priority):
There are several open bugs/feature requests in Valgrind that affect / would benefit Wine (roughly descending priority):
* Can't run wine under valgrind without patching either Wine or [https://bugs.kde.org/show_bug.cgi?id=344139 Valgrind bug #344139] - patch available
* [https://bugs.kde.org/show_bug.cgi?id=211031 valgrind doesn't show symbols for programs compiled with mingw's gcc]
* Programs compiled with mingw do not have debugging symbols (affects wine gecko and related components) [https://bugs.kde.org/show_bug.cgi?id=211031 Valgrind bug #211031]
* Provide SVN revision info in --version [https://bugs.kde.org/show_bug.cgi?id=352395 Valgrind bug #352395] - patch pending
 
These bugs may affect wine, but need to be retested:
* [https://bugs.kde.org/show_bug.cgi?id=126245 vex x86->IR: unhandled instruction bytes: 0x66 0x60 0xB8 0x1]
* [https://bugs.kde.org/show_bug.cgi?id=126245 vex x86->IR: unhandled instruction bytes: 0x66 0x60 0xB8 0x1]
* [https://bugs.kde.org/show_bug.cgi?id=148363 vex amd64->IR: unhandled instruction bytes: 0x65 0x4C 0x8B 0x1C (mov %gs:0x10,%r11)]
* [https://bugs.kde.org/show_bug.cgi?id=148363 vex amd64->IR: unhandled instruction bytes: 0x65 0x4C 0x8B 0x1C (mov %gs:0x10,%r11)]
* [https://bugs.kde.org/show_bug.cgi?id=189143 (wine) crash when running using wine to run vcsetup.exe under valgrind]
* [https://bugs.kde.org/show_bug.cgi?id=204536 want more contiguous user space for 32-bit process on 64-bit hardware]
* [https://bugs.kde.org/show_bug.cgi?id=204536 want more contiguous user space for 32-bit process on 64-bit hardware]
* [https://bugs.kde.org/show_bug.cgi?id=264785 wine's crypt32 message tests crash under valgrind, because of a jump to NULL]
* [https://bugs.kde.org/show_bug.cgi?id=264785 wine's crypt32 message tests crash under valgrind, because of a jump to NULL]
* [https://bugs.kde.org/show_bug.cgi?id=335563 wine's kernel32/thread test fails under valgrind]
* [https://bugs.kde.org/show_bug.cgi?id=335563 wine's kernel32/thread test fails under valgrind]
* [https://bugs.kde.org/show_bug.cgi?id=344382 MSVC 2013 compiled code has high error rates] Note: Wine can't deal with MSVC2013 pdb's anyway, see:
* [https://bugs.kde.org/show_bug.cgi?id=344382 Memcheck has high false error rates on MSVC2013 compiled, optimised, code] Note: Wine can't deal with MSVC2013 pdb's anyway, see:
** [https://bugs.winehq.org/show_bug.cgi?id=37746 Wine builtin dbghelp fails to process stream name table of PDBs created with recent Visual Studio 2010-2013 (mfc120.pdb)]
** [https://bugs.winehq.org/show_bug.cgi?id=37746 Wine builtin dbghelp fails to process stream name table of PDBs created with recent Visual Studio 2010-2013 (mfc120.pdb)]
** [https://bugs.winehq.org/show_bug.cgi?id=38594 dbghelp_msc:pe_load_debug_directory Got a page fault while loading symbols (Visual C++ 2013 .pdb's)]
** [https://bugs.winehq.org/show_bug.cgi?id=38594 dbghelp_msc:pe_load_debug_directory Got a page fault while loading symbols (Visual C++ 2013 .pdb's)]
** [https://bugs.winehq.org/show_bug.cgi?id=38604 winedbg: internal crash/hangs when running ieframe/tests/ie.c with pdb debug symbols]
** [https://bugs.winehq.org/show_bug.cgi?id=38604 winedbg: internal crash/hangs when running ieframe/tests/ie.c with pdb debug symbols]
* [https://bugs.kde.org/show_bug.cgi?id=348616 Wine/valgrind: Warning: noted but unhandled ioctl 0x5390 with no size/direction hints. (DVD_READ_STRUCT)] - patch pending
* [https://bugs.kde.org/show_bug.cgi?id=350228 Unhandled ioctl 0x6458 (i965/mesa)]
* [https://bugs.kde.org/show_bug.cgi?id=352767 Wine/valgrind: Warning: noted but unhandled ioctl 0x5307 with no size/direction hints. (CDROMSTOP)] - patch pending
* [https://bugs.kde.org/show_bug.cgi?id=339017 (meta) Valgrind 3.10 cannot load wine on OS X]
* [https://bugs.kde.org/show_bug.cgi?id=339017 (meta) Valgrind 3.10 cannot load wine on OS X]
* [https://bugs.kde.org/show_bug.cgi?id=349804 wine/osx: mmap-FIXED(0x1000, 1073741824) failed in UME (load_segment2)]
* [https://bugs.kde.org/show_bug.cgi?id=349804 wine/osx: mmap-FIXED(0x1000, 1073741824) failed in UME (load_segment2)]
If you want to use one of Valgrind's thread checking tools too (DRD or Helgrind), you're '''strongly recommended''' to apply the patch from [http://bugs.winehq.org/show_bug.cgi?id=24164 Bug Report #24164] '''before''' building Wine. This patch informs these tools that some functions, like ''EnterCriticalSection()'' and ''LeaveCriticalSection()'', are synchronization primitives. It also suppresses uninteresting memory access conflicts in Wine itself, and without this patch, either tool will report too many warnings to be useful.


== Alternatives to Valgrind ==
== Alternatives to Valgrind ==
Line 100: Line 78:


=== Open-Source Tools ===
=== Open-Source Tools ===
* [http://www.drmemory.org/ Dr. Memory] (memory checker based on the [http://dynamorio.org/ DynamoRIO framework])
* [https://www.drmemory.org/ Dr. Memory] (memory checker based on the [https://dynamorio.org/ DynamoRIO framework])
** Supported on all platforms
** Supported on all platforms
* [https://github.com/gperftools/gperftools gperftools] (Google Performance Tools for Unix)
* [https://github.com/gperftools/gperftools gperftools] (Google Performance Tools for Unix)
** Includes an efficient malloc implementation, plus heap & call-graph profilers
** Includes an efficient malloc implementation, plus heap & call-graph profilers
* [http://sourceforge.net/projects/fastmm/ FastMM] (fast memory-manager for C++ & Delphi programs)
* [https://sourceforge.net/projects/fastmm/ FastMM] (fast memory-manager for C++ & Delphi programs)
** Also includes memory checking tools
** Also includes memory checking tools
** Only for Windows
** Only for Windows
* [http://duma.sourceforge.net/ DUMA] (memory checker based on Bruce Perens' older Electric Fence library)
* [https://duma.sourceforge.net/ DUMA] (memory checker based on Bruce Perens' older Electric Fence library)
** Supported on Unix and Windows
** Supported on Unix and Windows
** Should still work but hasn't been updated since 2009
** Should still work but hasn't been updated since 2009
* [http://vld.codeplex.com/ Visual Leak Detector] (memory leak detector for Microsoft Visual C++)
* [https://kinddragon.github.io/vld/ Visual Leak Detector] (memory leak detector for Microsoft Visual C++)
** Only on Windows)
** Only on Windows


=== Freeware Tools ===
=== Freeware Tools ===
* [http://developer.amd.com/tools-and-sdks/opencl-zone/codexl/ AMD CodeXL] (profiling for both the CPU and GPU)
* [https://gpuopen.com/archived/legacy-codexl/ AMD CodeXL] (profiling for both the CPU and GPU)
** Only for AMD processors...
** Only for AMD processors...
** Consequently not available for Mac
** Consequently not available for Mac
Line 124: Line 102:


=== Commercial Tools ===
=== Commercial Tools ===
* [http://unicomsi.com/products/purifyplus/ Unicom PurifyPlus] (originally IBM Rational Purify)
* [https://www.teamblue.unicomsi.com/products/purifyplus/ Unicom PurifyPlus] (originally IBM Rational Purify)
** There are Linux & Mac versions too
** There are Linux & Mac versions too
* [http://www.parasoft.com/product/insure/ Parasoft Insure++] (memory-error checking suite)
* [https://www.parasoft.com/products/parasoft-insure/ Parasoft Insure++] (memory-error checking suite)
** Also has Linux & Mac versions
** Also has Linux & Mac versions
* [http://www.borland.com/Products/Software-Testing/Automated-Testing/Devpartner-Studio Borland DevPartner] (wide set of testing tools)
* [https://www.deleaker.com/ Deleaker] (memory profiler and leak detector for Microsoft Visual C++)
** Particularly well-known for the BoundsChecker tool
** Only supported on Windows
* [http://deleaker.com Deleaker] (memory profiler and leak detector for Microsoft Visual C++)
** Only for Windows
** Only for Windows
* [http://www.softwareverify.com/cpp-software-tools.php Software Verify C++ Suite] (several different testing tools)
* [https://www.softwareverify.com/products/ Software Verify C++ Suite] (several different testing tools)
** Only for Windows
** Only for Windows
* [https://software.intel.com/en-us/intel-inspector-xe Intel Inspector XE] (memory checking and thread debugging)
* [https://www.intel.com/content/www/us/en/developer/tools/oneapi/inspector.html#gs.tmgpje Intel Inspector XE] (memory checking and thread debugging)
** Only for Intel processors
** Only for Intel processors
** But otherwise supported on Windows, macOS, and Linux
** But otherwise supported on Windows, macOS, and Linux
* [http://www.glowcode.com/ Glowcode] (memory checking, profiling, and tracing)
* [https://www.glowcode.com/ Glowcode] (memory checking, profiling, and tracing)
** Only for Windows
** Only for Windows


Line 146: Line 121:
This should give you much lower overhead but at the price of much more work for you, the developer. Also note that this will '''only''' work on DLLs that never share allocated memory outside the scope of the DLL.
This should give you much lower overhead but at the price of much more work for you, the developer. Also note that this will '''only''' work on DLLs that never share allocated memory outside the scope of the DLL.


* For [http://www.winehq.org/pipermail/wine-patches/2006-October/031567.html msi]
* Old example for [https://www.winehq.org/pipermail/wine-patches/2006-October/031567.html msi]
* For [http://www.winehq.org/pipermail/wine-patches/2006-October/032143.html richedit]
* Old example for [https://www.winehq.org/pipermail/wine-patches/2006-October/032143.html richedit]


== See Also ==
== See Also ==
* [https://developer.mozilla.org/en-US/docs/Debugging_Mozilla_with_Valgrind Debugging Mozilla with Valgrind] has a good case-study showing how to use Valgrind
* [https://developer.mozilla.org/en-US/docs/Debugging_Mozilla_with_Valgrind Debugging Mozilla with Valgrind] has a good case-study showing how to use Valgrind
* [http://bugs.winehq.org/buglist.cgi?quicksearch=valgrind Wine bugs] involving or detected by Valgrind
* [https://bugs.winehq.org/buglist.cgi?quicksearch=valgrind Wine bugs] involving or detected by Valgrind
* [https://bugs.kde.org/buglist.cgi?product=valgrind&long_desc_type=substring&long_desc=wine&bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=NEEDSINFO Valgrind bugs] with Wine mentioned in the comments
* [https://bugs.kde.org/buglist.cgi?product=valgrind&long_desc_type=substring&long_desc=wine&bug_status=UNCONFIRMED&bug_status=CONFIRMED&bug_status=ASSIGNED&bug_status=REOPENED&bug_status=NEEDSINFO Valgrind bugs] with Wine mentioned in the comments



Latest revision as of 23:01, 1 April 2023

Valgrind is a set of tools aimed at finding bugs and performance problems in programs. By default, it catches reads of uninitialized memory, accesses to inaccessible memory, and memory leaks. It's useful for debugging wine itself, as well as windows apps running on Wine.

  • To get the full power of Valgrind while debugging Wine, you need to build Wine from source after installing Valgrind. You'll also want to switch off certain compiler optimizations; the Developer Tools section of the Building Wine page has more details.
  • Valgrind will work on macOS (starting with partial support in macOS v10.8 "Mountain Lion"). If you want line numbers with Valgrind on Mac, don't forget to tell Xcode to generate a .dSYM file, though you can also use gdb after the fact to look up line numbers.
  • In applications built with the debug version of the MS Visual C/C++ runtime, memory allocated via malloc() is always initialized. This obscures any uninitialized memory accesses that would normally appear from Valgrind (see Memory Management and the Debug Heap at MSDN for the full story).


Running Wine under Valgrind

To analyze a program running on Wine with Valgrind, just call valgrind with the appropriate options in front of the normal wine command. For example:

valgrind --trace-children=yes --vex-iropt-register-updates=allregs-at-mem-access wine foo.exe


Note that this command will also trace the ["wineserver"] if foo.exe is the first Wine application running. Unless you're specifically looking to debug wineserver (usually you'll be more interested in specific dlls), this is a waste of resources. Valgrind can be pretty intensive on the CPU so you can speed things up quite a bit by not starting the wineserver under Valgrind.

To do that, just start a dummy program under Wine first (e.g. notepad or winemine), then without closing that program, start your desired program through wine and valgrind as you normally would.

Valgrind Options Relevant for Wine

Over the years, several Valgrind options have turned out to be necessary, or at least very helpful, when analyzing Wine. Two in particular are necessary for Wine to function well under Valgrind:

Several more are useful for suppressing known bugs or exceptions in Wine:

This option can be repeated with multiple files

  • --partial-loads-ok=yes silences warnings for when bit-alignments overlap both addressable and illegal ranges. In particular, try this if the last three bytes of allocations throw a lot of "Invalid Read of Size N" warnings.


There's a good chance these are false positives from vectorized string operations (Valgrind Bug Report #264936 has more info). In the Valgrind bug report, someone also mentions using GCC with the -fno-builtin-strdup compiler option to make the warnings disappear. It hasn't been tested with Wine, but the Compiler Optimizations section of Building Wine has more details about changing compiler flags while building Wine.

Controlling Memory Leak Reports

There are a few more Valgrind options that let you fine-tune how much it reports about memory leaks. By default, Valgrind only gives a count of memory leaks detected at the end of execution.

To get more info, you want to pass the --leak-check=full flag when running Valgrind. This will give you individual reports about certain types of memory leaks (but not all). Once this option is set, you can use several other options to specify which kinds of memory leaks you want detailed reports for:


Finally, by passing the --track-origins=yes option, you can ask Valgrind to give you stack backtraces to the point where a leaky memory block was allocated. This is terrifically helpful for debugging, but it has the downside of making valgrind run even slower.

Conformance Tests under Valgrind

To run Wine's ConformanceTests under Valgrind, you mainly need to set the WINETEST_WRAPPER and VALGRIND_OPTS variables, e.g...

export VALGRIND_OPTS="--trace-children=yes --track-origins=yes --gen-suppressions=all --suppressions=$HOME/valgrind-suppressions-ignore --suppressions=$HOME/valgrind-suppressions-external --num-callers=20 --vex-iropt-register-updates=allregs-at-mem-access"
WINETEST_WRAPPER=valgrind make -k test > test.log 2>&1


Along with suppression files, Austin English's github repo also has some scripts to help run the tests under Valgrind.

Changes to Wine Source

There are also some tweaks you can make to the Wine source code itself that might help you uncover other problems. First, the Wine source defines two constants that can be quickly changed and might reveal more bugs:

  • MAX_FREE_PENDING controls how long freed blocks are kept out of circulation and is set to 1024 by default. If you think your app is hanging on to freed pointers longer than it should, increasing it and recompiling wine might help Valgrind detect use-after-free errors.
  • HEAP_TAIL_EXTRA_SIZE gives the size of the redzone at the end of each block. If your app nests really big structs within another struct or array, you might need to increase this to catch overrun errors. Watch out though because increasing it beyond 32 or so bytes can cause strange false positives sometimes.

Valgrind Bugs / Feature Requests

There are several open bugs/feature requests in Valgrind that affect / would benefit Wine (roughly descending priority):

Alternatives to Valgrind

At least on Unix and among free, open-source tools, Valgrind is arguably the gold standard for dynamic analysis suites. It offers many features that most other execution-analysis tools don't (not least of which that it's free, it's fast and it can handle Mac and Linux apps too). In fact, if you're a Windows developer, you might want to consider testing your program on Wine just to get Valgrind.

If for whatever reason you don't want to use Valgrind though, or you want to run a tool natively on Windows, there are several free and commercial ones.

Open-Source Tools

  • Dr. Memory (memory checker based on the DynamoRIO framework)
    • Supported on all platforms
  • gperftools (Google Performance Tools for Unix)
    • Includes an efficient malloc implementation, plus heap & call-graph profilers
  • FastMM (fast memory-manager for C++ & Delphi programs)
    • Also includes memory checking tools
    • Only for Windows
  • DUMA (memory checker based on Bruce Perens' older Electric Fence library)
    • Supported on Unix and Windows
    • Should still work but hasn't been updated since 2009
  • Visual Leak Detector (memory leak detector for Microsoft Visual C++)
    • Only on Windows

Freeware Tools

  • AMD CodeXL (profiling for both the CPU and GPU)
    • Only for AMD processors...
    • Consequently not available for Mac
  • MS Application Verifier (Windows runtime test-suite)
    • Runs several tests, including memory checking, on Windows applications
    • Part of the Windows SDK and only available on Windows
  • Debugging Tools for Windows (set of debuggers from Microsoft)
    • Only for Windows naturally

Commercial Tools

  • Unicom PurifyPlus (originally IBM Rational Purify)
    • There are Linux & Mac versions too
  • Parasoft Insure++ (memory-error checking suite)
    • Also has Linux & Mac versions
  • Deleaker (memory profiler and leak detector for Microsoft Visual C++)
    • Only for Windows
  • Software Verify C++ Suite (several different testing tools)
    • Only for Windows
  • Intel Inspector XE (memory checking and thread debugging)
    • Only for Intel processors
    • But otherwise supported on Windows, macOS, and Linux
  • Glowcode (memory checking, profiling, and tracing)
    • Only for Windows

Ad-Hoc Patches

Most separate profiling tools will significantly affect Wine's performance. If this is a problem, you may be able to take a different approach: patch the wine DLL so it can detect errors itself.

This should give you much lower overhead but at the price of much more work for you, the developer. Also note that this will only work on DLLs that never share allocated memory outside the scope of the DLL.

See Also

This page was last edited on 1 April 2023, at 23:01.