WineHQ

Wine and Valgrind: Difference between revisions

(Merge in alternative runtime tools and nest headings when appropriate)
(remove some fixed bugs)
(4 intermediate revisions by 2 users not shown)
Line 5: Line 5:
*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.
*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 ["MacOSX"] (starting with partial support in MacOSX 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 ''[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).
Line 27: Line 27:
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)
* ''[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)
* ''[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. AustinEnglish 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.
* ''[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.
Line 53: Line 53:




Along with suppression files, AustinEnglish's [https://github.com/austin987/wine_misc/tree/master/valgrind github repo] also has some scripts to help run the tests under Valgrind.
Along with suppression files, [[User:Austin987|Austin English's]] [https://github.com/austin987/wine_misc/tree/master/valgrind github repo] also has some scripts to help run the tests under Valgrind.


== Changes to Wine Source ==
== Changes to Wine Source ==
Line 69: Line 69:
* Adjust timeout interval for virtulaizers ([https://bugs.winehq.org/show_bug.cgi?id=14370 Bug #14370])
* Adjust timeout interval for virtulaizers ([https://bugs.winehq.org/show_bug.cgi?id=14370 Bug #14370])


== Valgrind Bugs / Feature Requests ==
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
* 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]
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=148363 vex amd64->IR: unhandled instruction bytes: 0x65 0x4C 0x8B 0x1C (mov %gs:0x10,%r11)]
* [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=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.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=38604 winedbg: internal crash/hangs when running ieframe/tests/ie.c with pdb debug symbols]
* [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)]


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.
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.
Line 115: Line 132:
* [https://software.intel.com/en-us/intel-inspector-xe Intel Inspector XE] (memory checking and thread debugging)
* [https://software.intel.com/en-us/intel-inspector-xe Intel Inspector XE] (memory checking and thread debugging)
** Only for Intel processors
** Only for Intel processors
** But otherwise supported on Windows, Mac OSX, and Linux
** But otherwise supported on Windows, macOS, and Linux
* [http://www.glowcode.com/ Glowcode] (memory checking, profiling, and tracing)
* [http://www.glowcode.com/ Glowcode] (memory checking, profiling, and tracing)
** Only for Windows
** Only for Windows

Revision as of 16:29, 28 November 2017

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 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 "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.
  • 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 --workaround-gcc296-bugs=yes 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  --workaround-gcc296-bugs=yes --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.

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[] (Bug #14359)
  • Co-operate with valgrind at execv (Bug #14361)
  • Enhance loader and wine_main_preload_info for valgrind (Bug #14364)
  • Do not touch high address space (initial stack, user_space_limit) (Bug #14365)
  • Co-operate with valgrind when switching stacks (Bug #14366)
  • Adjust timeout interval for virtulaizers (Bug #14370)

Valgrind Bugs / Feature Requests

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 Valgrind bug #344139 - patch available
  • Programs compiled with mingw do not have debugging symbols (affects wine gecko and related components) Valgrind bug #211031

These bugs may affect wine, but need to be retested:

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 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

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
  • Borland DevPartner (wide set of testing tools)
    • Particularly well-known for the BoundsChecker tool
    • Only supported on Windows
  • 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 28 November 2017, at 16:29.