summaryrefslogtreecommitdiffstats
path: root/docs/contributing/debugging/debugging_on_windows.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/contributing/debugging/debugging_on_windows.rst')
-rw-r--r--docs/contributing/debugging/debugging_on_windows.rst439
1 files changed, 439 insertions, 0 deletions
diff --git a/docs/contributing/debugging/debugging_on_windows.rst b/docs/contributing/debugging/debugging_on_windows.rst
new file mode 100644
index 0000000000..34854c5694
--- /dev/null
+++ b/docs/contributing/debugging/debugging_on_windows.rst
@@ -0,0 +1,439 @@
+Debugging On Windows
+====================
+
++--------------------------------------------------------------------+
+| This page is an import from MDN and the contents might be outdated |
++--------------------------------------------------------------------+
+
+This document explains how to debug Gecko based applications such as
+Firefox, Thunderbird, and SeaMonkey on Windows using the Visual C++ IDE.
+
+If VC++ and your Gecko application hang shortly after you launch the
+application under the debugger, see `Problems Loading Debug
+Symbols <#problems-loading-debug-symbols>`__.
+
+Ways to start the debugger
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+First of all, it's necessary to install a Visual Studio extension to be
+able to follow child processes as they are created. Firefox, in general,
+and even in non-e10s mode, does not start the main process directly, it
+starts it via a Launcher Process. This means that Visual Studio will
+only attach to the first process it finds, and will not hit any
+break-point (and even notifies you that it cannot find their location).
+`Microsoft Child Process Debugging Power
+Tool <https://marketplace.visualstudio.com/items?itemName=vsdbgplat.MicrosoftChildProcessDebuggingPowerTool>`__
+allows automatically attaching to child processes, such as Web Content
+process, GPU process, etc. Enable it by going its configuration menu in
+"Debug > Other debugging targets > Child process debugging settings",
+and ticking the box.
+
+If you have followed the steps in :ref:`Building Firefox for
+Windows <Building Firefox On Windows>`
+and have a local debug build, you can **execute ``./mach run --debug``**
+from the same command line. It would open Visual Studio with Firefox's
+run options configured. You can **click "Start" button** to run Firefox
+then, already attached in the debugger.
+
+Alternatively, if you have generated the Visual Studio solution, via
+``./mach build-backend -b VisualStudio``, opening this solution allows
+you to run ``firefox.exe`` directly in the debugger. Making it the
+startup project, by right clicking on it (it appears bold when it's the
+case) can be useful. Breakpoints are kept across runs, this can be a
+good way to debug startup issues.
+
+**Run the program until you hit an assertion.** You will get a dialog
+box asking if you would like to debug. Hit "Cancel". The MSDEV IDE will
+launch and load the file where the assertion happened. This will also
+create a Visual C++ Mozilla project in the directory of the executable
+by default.
+
+**Attach the debugger to an existing Mozilla process**. In the Visual
+Studio, select Debug > Attach to Process. If you want to debug a content
+process, you can **hover on the tab** of page you want to debug, which
+would show the pid. You can then select the process from dialog opened
+from "Attach to Process". For more information, see `Attach to Running
+Processes with the Visual Studio
+Debugger <http://msdn.microsoft.com/en-us/library/vstudio/3s68z0b3.aspx>`__.
+
+Debugging Release and Nightly Builds
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Refer to the steps to :ref:`use the Mozilla symbol
+server <Using The Mozilla Symbol Server>` and :ref:`source
+server <Using The Mozilla Source Server>`
+
+Creating a Visual C++ project for Firefox
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Please refer to :ref:`this <Visual Studio Projects>`.
+
+Changing/setting the executable to debug
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+VC++ 6.0: To change or set the executable to debug, go to Project >
+Settings..., Debug tab and select General from the drop down list.
+"Executable for debug session:" should show the executable you are
+debugging. If it is empty or incorrect, use the arrow button and select
+Browse... to locate the executable.
+
+Command line parameters and environment variables
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+VC++ 6.0: To change or set the command line options, go to Project >
+Settings..., Debug tab and select General from the drop down list.
+"Program arguments:" should show the options.
+
+Some common options would be the URL of the file you want the browser to
+open as soon as it starts, starting the Profile Manager, or selecting a
+profile. You can also redirect the console output to a file (by adding
+"``> filename.txt``" for example, without the quotes).
+
+In VC 7 and 8 this option is called Project > Properties > Debugging >
+Command Arguments. VC 8 also allows you to set environment variables
+there.
+
+Setting breakpoints in DLLs which are not yet loaded in memory
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+VC++ 6.0: Go to Project > Settings..., Debug tab and select "Additional
+DLLs" from the drop down list. Check "Locate Additional DLLs" option.
+For each DLL, click the "New" button which creates a new entry and then
+hit the "..." buttons which lets you browse to the DLL. You will only be
+able to add one DLL at a time.
+
+VC++ 7.0 automatically finds additional DLLs.
+
+Customizing the debugger's variable value view
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can customize how Visual C++ displays classes in the variable view.
+By default VC++ displays "{...}" and you need to click the small + icon
+to expand the members. You can change this behaviour, and make Visual
+C++ display whatever data member you want in whatever order, formatter
+however you like instead of just "{...}".
+
+You need to locate a file called "AUTOEXP.DAT" in your Visual C++
+installation. By default it will be:
+
+VC++ 6.0:
+
+.. code::
+
+ C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin\AUTOEXP.DAT
+
+VC++ 7.0:
+
+.. code::
+
+ C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\Debugger\AUTOEXP.DAT
+
+The file has information about the format in the beginning, and after a
+little practice you should be well on your way. Here are some entries
+that will make your life easier:
+
+::
+
+ ;; Mozilla (1.7beta and later)
+ nsAutoString=<mData,su>
+ nsString=<mData,su>
+ nsCString=<mData,s>
+ nsCAutoString=<mData,s>
+ nsRect=x=<x,d> y=<y,d> width=<width,d>; height=<height,d>
+ nsStaticAtomWrapper=<mStaticAtom->mString,s>
+ nsIAtom=<mString,su>
+ ; the following are not necessary in vc8
+ nsCOMPtr<*>=<mRawPtr,x>
+ nsRefPtr=<mRawPtr,x>
+ nsAutoPtr=<mRawPtr,x>
+
+After you have made the changes and saved the file, you will need to
+restart Visual C++ for the changes to take effect.
+
+For XPCOM Strings (the "external" string API) you can use the following
+values:
+
+::
+
+ ;; Mozilla (1.9)
+ ; Internal Strings
+ nsAString_internal=<mData,su>, length=<mLength,u>
+ nsACString_internal=<mData,s>, length=<mLength,u>
+ ; XPCOM Strings
+ nsAString=<nsStringContainer.v,su>, length=<nsStringContainer.d1,u>
+ nsACString=<nsCStringContainer.v,s>, length=<nsCStringContainer.d1,u>
+ nsStringContainer=<v,su>, length=<d1,u>
+ nsCStringContainer=<v,s>, length=<d1,u>
+
+There is a more extensive version of this file in progress in
+`AutoExpForVC8. <https://developer.mozilla.org/en-US/docs/Mozilla/Debugging/AutoExpForVC8>`__
+
+Avoiding stepping into certain functions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can avoid stepping into certain functions, such as nsCOMPtr methods,
+using an undocumented feature of VC. See the blog post `How to Not Step
+Into Functions using the Visual C++
+Debugger <http://blogs.msdn.com/andypennell/archive/2004/02/06/69004.aspx>`__
+for details.
+
+Here are some wildcards you can use (tested with VC 8):
+
+.. code::
+
+ nsCOMPtr.*\:\:.*=NoStepInto
+ (nsG|g)etter_*AddRefs.*=NoStepInto
+ NS_ConvertUTF.*
+ ; Might be too broad:
+ (ns|Promise)[^\:]*[sS]tring.*
+ ...add common functions to this list
+
+should probably make a .reg file for easy importing
+
+Obtaining ``stdout`` and other ``FILE`` handles
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Running the following command in the Command Window in Visual Studio
+returns the value of ``stdout``, which can be used with various
+debugging methods (such as ``nsGenericElement::List``) that take a
+``FILE*`` param:
+
+.. code::
+
+ Debug.EvaluateStatement {,,msvcr80d}(&__iob_func()[1])
+
+(Alternatively you can evaluate ``{,,msvcr80d}(&__iob_func()[1])`` in
+the QuickWatch window)
+
+Similarly, you can open a file on the disk using ``fopen``:
+
+.. code::
+
+ >Debug.EvaluateStatement {,,msvcr80d}fopen("c:\\123", "w")
+ 0x10311dc0 { ..snip.. }
+ >Debug.EvaluateStatement ((nsGenericElement*)0x03f0e710)->List((FILE*)0x10311dc0, 1)
+ <void>
+ >Debug.EvaluateStatement {,,msvcr80d}fclose((FILE*)0x10311dc0)
+ 0x00000000
+
+Note that you may not see the debugging output until you flush or close
+the file handle.
+
+Disabling ASSERTIONS
+~~~~~~~~~~~~~~~~~~~~
+
+There are basically two ways to disable assertions. One requires setting
+an environment variable, while the other affects only the currently
+running program instance in memory.
+
+Environment variable
+^^^^^^^^^^^^^^^^^^^^
+
+There is an environment variable that can disable breaking for
+assertions. This is how you would normally set it:
+
+.. code::
+
+ set XPCOM_DEBUG_BREAK=warn
+
+The environment variable takes also other values besides ``warn``, see
+``XPCOM_DEBUG_BREAK`` for more details.
+
+Note that unlike Unix, the default for Windows is not warn, it's to pop
+up a dialog. To set the environment variable for Visual Studio, use
+Project > Properties > Debugging > Environment and click the little box.
+Then use
+
+.. code::
+
+ XPCOM_DEBUG_BREAK=warn
+
+Changing running code
+^^^^^^^^^^^^^^^^^^^^^
+
+You normally shouldn't need to do this (just quit the application, set
+the environment variable described above, and run it again). And this
+can be **dangerous** (like **trashing your hard disc and corrupting your
+system**). So unless you feel comfortable with this, don't do it. **You
+have been warned!**
+
+It is possible to change the interrupt code in memory (which causes you
+to break into debugger) to be a NOP (no operation).
+
+You do this by running the program in the debugger until you hit an
+assertion. You should see some assembly code. One assemly code
+instruction reads "int 3". Check the memory address for that line. Now
+open memory view. Type/copy/drag the memory address of "int 3" into the
+memory view to get it to update on that part of the memory. Change the
+value of the memory to "90", close the memory view and hit "F5" to
+continue.
+
+| Confused? See the screenshot below:
+| |Screenshot of disabling assertions|
+
+VC++ 7.0?
+
+Automatically handling ASSERTIONS without a debugger attached
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When an assertion happens and there is not a debugger attached, a small
+helper application
+(```windbgdlg.exe`` </En/Automatically_Handle_Failed_Asserts_in_Debug_Builds>`__)
+is run. That application can automatically select a response to the "Do
+you want to debug" dialog instead of prompting if you configure it, for
+more info, see
+```windbgdlg.exe`` </En/Automatically_Handle_Failed_Asserts_in_Debug_Builds>`__.
+
+Debugging optimized builds
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To effectively debug optimized builds, you should enable debugging
+information which effectively leaves the debug symbols in optimized code
+so you can still set breakpoints etc. Because the code is optimized,
+stepping through the code may occasionally provide small surprises when
+the debugger jumps over something.
+
+You need to make sure this configure parameter is set:
+
+.. code::
+
+ --enable-debugger-info-modules=yes
+
+You can also choose to include or exclude specific modules. This is
+particularly useful to avoid linking layout with debugging information.
+
+Console debugging
+~~~~~~~~~~~~~~~~~
+
+When printing to STDOUT from a content process, the console message will
+not appear on Windows. One way to view it is simply to disable e10s
+(``./mach run --disable-e10s``) but in order to debug with e10s enabled
+one can run
+
+::
+
+ ./mach run ... 2>&1 | tee
+
+It may also be necessary to disable the content sandbox
+(``MOZ_DISABLE_CONTENT_SANDBOX=1 ./mach run ...``).
+
+Running two instances of Mozilla simultaneously
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can run two instances of Mozilla (e.g. debug and optimized)
+simultaneously by setting the environment variable ``MOZ_NO_REMOTE``:
+
+.. code::
+
+ set MOZ_NO_REMOTE=1
+
+Or, starting with Firefox 2 and other Gecko 1.8.1-based applications,
+you can use the ``-no-remote`` command-line switch instead (implemented
+in
+`bug 325509 <https://bugzilla.mozilla.org/show_bug.cgi?id=325509>`__).
+
+You can also specify the profile to use with the ``-P profile_name``
+command-line argument.
+
+Debugging JavaScript
+~~~~~~~~~~~~~~~~~~~~
+
+Use `Venkman <https://developer.mozilla.org/en-US/docs/Archive/Mozilla/Venkman>`__, the JavaScript Debugger for Mozilla.
+
+You can use helper functions from
+`nsXPConnect.cpp <https://searchfox.org/mozilla-central/source/js/xpconnect/src/nsXPConnect.cpp>`__
+to inspect and modify the state of JavaScript code from the MSVS
+debugger.
+
+For example, to print current JavaScript stack to stdout, evaluate this
+in QuickWatch window:
+
+.. code::
+
+ {,,xul}DumpJSStack()
+
+Visual C++ will show you something in the quick watch window, but
+not the stack, you have to look in the OS console for the output.
+
+Also this magical command only works when the VC++ stack is in certain
+states. It works when you have js_Interpret() in the newest stackframe
+
+Debugging minidumps
+~~~~~~~~~~~~~~~~~~~
+
+See :ref:`debugging a minidump <Debugging A Minidump>`.
+
+Debugging tinderbox builds
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+See `Running Windows Debug Builds <https://developer.mozilla.org/en-US/docs/Archive/Mozilla/Running_Windows_Debug_Builds>`__
+
+Problems Loading Debug Symbols
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If both your application and Visual C++ hang shortly after launching the
+application under the debugger, you may be hitting a known deadlock in
+the way Visual Studio downloads debug symbols for the system libraries;
+see
+https://connect.microsoft.com/VisualStudio/feedback/details/422970/hang-loading-rasapi32-pdb-when-using-symbol-server.
+
+There are two ways to work around this problem:
+
+#. Turn off automatic symbol downloading for system libraries: in Tools
+ > Options > Debugging > Symbols, uncheck the Microsoft symbol server.
+#. Pre-load all the Windows debug symbols. These instructions apply to
+ Visual Studio 10 on Windows 7; other software versions likely need to
+ have file paths adjusted.
+
+ #. Locate the Microsoft utility "SymChk.exe" on your system (it will
+ likely be in the installation directory of your Windows Debugging
+ Tools).
+
+ #. Find the directory where Visual Studio caches downloaded symbols;
+ in VC++ 10 open the menu to Tools > Options > Debugging > Symbols
+ and copy the field "Cache symbols in this directory".
+
+ #. In a command window, run
+
+ ::
+
+ symchk.exe /r C:\windows\SysWOW64\ /s "SRV*<your cache symbols directory>\MicrosoftPublicSymbols*http://msdl.microsoft.com/download/symbols"
+
+ |
+ | Note the "``\MicrosoftPublicSymbols``" appended to the cache
+ directory configured in Visual Studio.
+
+Downloading all symbols can take a long time; you can replace
+C:\windows\SysWOW64\\ with the name of a single .DLL to download symbols
+only for the specific libraries you are trying to debug. Unfortunately,
+it's hard to know which symbols to download without having VS hang and
+seeing the "Downloading symbols for <library>" status at the bottom left
+of the main window.
+
+Problems post-mortem debugging on Windows 7 SP1 x64?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you attempt to use ``NS_DebugBreak`` etc to perform post-mortem
+debugging on a 64bit Windows 7, but as soon as you try and continue
+debugging the program crashes with an Access Violation, you may be
+hitting a Windows bug relating to AVX support. For more details,
+including a work-around see `this blog
+post <http://www.os2museum.com/wp/?p=960>`__ or `this social.msdn
+thread <http://social.msdn.microsoft.com/Forums/vstudio/en-US/392ca62c-e502-42d9-adbc-b4e22d5da0c3/jit-debugging-32bit-app-crashing-with-access-violation>`__.
+(And just in-case those links die, the work-around is to execute
+
+::
+
+ bcdedit /set xsavedisable 1
+
+from an elevated command-prompt to disable AVX support.)
+
+Got a tip?
+~~~~~~~~~~
+
+If you think you know a cool Mozilla debugging trick, feel free to
+discuss it with `#developers <https://chat.mozilla.org/#/room/#developers:mozilla.org>`__ and
+then post it here.
+
+.. |Screenshot of disabling assertions| image:: https://developer.mozilla.org/@api/deki/files/420/=Win32-debug-nop.png
+ :class: internal