summaryrefslogtreecommitdiff
path: root/Documentation
diff options
context:
space:
mode:
authorJames Ko <jamesqko@gmail.com>2016-06-01 17:19:22 +0000
committerJames Ko <jamesqko@gmail.com>2016-06-01 17:19:22 +0000
commit27e4328891ca3ce83fcd6881556d57d183b2b284 (patch)
treeb9018bcac95e29b25a56bf23869ddfda05653100 /Documentation
parent80b11809300d2b762a5ce09bf5a69d9f7003d06b (diff)
downloadcoreclr-27e4328891ca3ce83fcd6881556d57d183b2b284.tar.gz
coreclr-27e4328891ca3ce83fcd6881556d57d183b2b284.tar.bz2
coreclr-27e4328891ca3ce83fcd6881556d57d183b2b284.zip
Add new document on how to setup/view JIT dumps
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/botr/ryujit-overview.md62
-rw-r--r--Documentation/building/viewing-jit-dumps.md173
-rwxr-xr-xDocumentation/project-docs/clr-complus-conf-docgen.sh2
-rw-r--r--Documentation/project-docs/clr-configuration-knobs.md5
4 files changed, 189 insertions, 53 deletions
diff --git a/Documentation/botr/ryujit-overview.md b/Documentation/botr/ryujit-overview.md
index a084879626..ee84a9a9dc 100644
--- a/Documentation/botr/ryujit-overview.md
+++ b/Documentation/botr/ryujit-overview.md
@@ -488,63 +488,27 @@ Debug info consists primarily of two types of information in the JIT:
Exception handling information is captured in an `EHblkDsc` for each exception handling region. Each region includes the first and last blocks of the try and handler regions, exception type, enclosing region, among other things. Look at [jiteh.h](https://github.com/dotnet/coreclr/blob/master/src/jit/jiteh.h) and [jiteh.cpp](https://github.com/dotnet/coreclr/blob/master/src/jit/jiteh.cpp), especially, for details. Look at `Compiler::fgVerifyHandlerTab()` to see how the exception table constraints are verified.
-# Dumps and Other Tools
-
-The behavior of the JIT can be controlled via a number of configuration variables. These are declared in [inc/clrconfigvalues.h](https://github.com/dotnet/coreclr/blob/master/src/inc/clrconfigvalues.h). When used as an environment variable, the string name generally has “COMPlus_” prepended. When used as a registry value name, the configuration name is used directly.
-
-## Setting configuration variables
-
-These can be set in one of three ways:
-
-* Setting the environment variable `COMPlus_<flagname>`. For example, the following will set the `JitDump` flag so that the compilation of all methods named ‘Main’ will be dumped:
-
- set COMPlus_JitDump=Main
-
-* Setting the registry key `HKCU\Software\Microsoft\.NETFramework`, Value `<flagName>`, type `REG_SZ` or `REG_DWORD` (depending on the flag).
-* Setting the registry key `HKLM\Software\Microsoft\.NETFramework`, Value `<flagName>`, type `REG_SZ` or `REG_DWORD` (depending on the flag).
-
-## Specifying method names
-
-The complete syntax for specifying a single method name (for a flag that takes a method name, such as `COMPlus_JitDump`) is:
-
- [[<Namespace>.]<ClassName>::]<MethodName>[([<types>)]
-
-For example
-
- System.Object::ToString(System.Object)
-
-The namespace, class name, and argument types are optional, and if they are not present, default to a wildcard. Thus stating:
-
- Main
-
-will match all methods named Main from any class and any number of arguments.
-
-<types> is a comma separated list of type names. Note that presently only the number of arguments and not the types themselves are used to distinguish methods. Thus, Main(Foo, Bar), and Main(int, int) will both match any main method with two arguments.
-
-The wildcard character ‘*’ can be used for <ClassName> and <MethodName>. In particular * by itself indicates every method.
+# Reading a JitDump
-## Useful COMPlus variables
+One of the best ways of learning about the JIT compiler is examining a compilation dump in detail. The dump shows you all the really important details of the basic data structures without all the implementation detail of the code. Debugging a JIT bug almost always begins with a JitDump. Only after the problem is isolated by the dump does it make sense to start debugging the JIT code itself.
-Below are some of the most useful `COMPlus` variables. Where {method-list} is specified in the list below, you can supply a space-separated list of either fully-qualified or simple method names (the former is useful when running something that has many methods of the same name), or you can specific ‘*’ to mean all methods.
+Dumps are also useful because they give you good places to place breakpoints. If you want to see what is happening at some point in the dump, simply search for the dump text in the source code. This gives you a great place to put a conditional breakpoint.
-* `COMPlus_JitDump`={method-list} – dump lots of useful information about what the JIT is doing (see below).
-* `COMPlus_JitDisasm`={method-list} – dump a disassembly listing of each method.
-* `COMPlus_JitDiffableDasm` – set to 1 to tell the JIT to avoid printing things like pointer values that can change from one invocation to the next, so that the disassembly can be more easily compared.
-* `COMPlus_JitGCDump`={method-list} – dump the GC information.
-* `COMPlus_JitUnwindDump`={method-list} – dump the unwind tables.
-* `COMPlus_JitEHDump`={method-list} – dump the exception handling tables.
-* `COMPlus_JitTimeLogFile`={file name} – this specifies a log file to which timing information is written.
-* `COMPlus_JitTimeLogCsv`={file name} – this specifies a log file to which summary timing information can be written, in CSV form.
+There is not a strong convention about what or how the information is dumped, but generally you can find phase-specific information by searching for the phase name. Some useful points follow.
-See also: [CLR Configuration Knobs](../project-docs/clr-configuration-knobs.md)
+## How to create a JitDump
-# Reading a JitDump
+You can enable dumps by setting the `COMPlus_JitDump` environment variable to a space-separated list of the method(s) you want to dump. For example:
-One of the best ways of learning about the JIT compiler is examining a compilation dump in detail. The dump shows you all the really important details of the basic data structures without all the implementation detail of the code. Debugging a JIT bug almost always begins with a JitDump. Only after the problem is isolated by the dump does it make sense to start debugging the JIT code itself.
+```cmd
+:: Print out lots of useful info when
+:: compiling methods named Main/GetEnumerator
+set "COMPlus_JitDump=Main GetEnumerator"
+```
-Dumps are also useful because they give you good places to place breakpoints. If you want to see what is happening at some point in the dump, simply search for the dump text in the source code. This gives you a great place to put a conditional breakpoint.
+See [Setting configuration variables](../building/viewing-jit-dumps.md#setting-configuration-variables) for more details on this.
-There is not a strong convention about what or how the information is dumped, but generally you can find phase-specific information by searching for the phase name. Some useful points follow.
+Full instructions for dumping the compilation of some managed code can be found here: [viewing-jit-dumps.md](../building/viewing-jit-dumps.md)
## Reading expression trees
diff --git a/Documentation/building/viewing-jit-dumps.md b/Documentation/building/viewing-jit-dumps.md
new file mode 100644
index 0000000000..5303b47626
--- /dev/null
+++ b/Documentation/building/viewing-jit-dumps.md
@@ -0,0 +1,173 @@
+# Viewing JIT Dumps
+
+This document is intended for people interested in seeing the disassembly, GC info, or other details the JIT generates for a managed program.
+
+To make sense of the results, it is recommended you also read the [Reading a JitDump](../botr/ryujit-overview.md#reading-a-jitdump) section of the RyuJIT Overview.
+
+## Setting up our environment
+
+The first thing we want to do is setup the .NET Core app we want to dump. Here are the steps to do this, if you don't have one ready:
+
+* Perform a debug build of the CoreCLR repo
+* Install the [.NET CLI](http://microsoft.com/net/core), which we'll use to compile/publish our app
+* `cd` to where you want your app to be placed, and run `dotnet new`
+* Modify your `project.json` file so that it contains a RID (runtime ID) corresponding to the OS you're using in the `runtimes` section. For example, I have a Windows 10 x64 machine, so here's my project file:
+
+```json
+{
+ "buildOptions": {
+ "emitEntryPoint": true
+ },
+ "dependencies": {
+ "Microsoft.NETCore.App": "1.0.0-*"
+ },
+ "frameworks": {
+ "netcoreapp1.0": {
+ "imports": [
+ "dnxcore50",
+ "portable-net45+win8"
+ ]
+ }
+ },
+ "runtimes": {
+ "win10-x64": {}
+ }
+}
+```
+
+You can find a list of RIDs and their corresponding OSes [here](http://dotnet.github.io/docs/core-concepts/rid-catalog.html).
+
+* Edit `Program.cs`, and call the method(s) you want to dump in there. Make sure they are, directly or indirectly, called from `Main`. In this example, we'll be looking at the disassembly of our custom function `InefficientJoin`:
+
+```cs
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+
+namespace ConsoleApplication
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ Console.WriteLine(InefficientJoin(args));
+ }
+
+ // Add NoInlining to prevent this from getting
+ // mixed up with the rest of the code in Main
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private static string InefficientJoin(IEnumerable<string> args)
+ {
+ var result = string.Empty;
+ foreach (var arg in args) result += (arg + ' ');
+ return result.Substring(0, result.Length - 1);
+ }
+ }
+}
+```
+
+* After you've finished editing the code, run `dotnet publish -c Release`. This should drop all of the binaries needed to run your app in `bin/Release/<configuration>/<rid>/publish`.
+* Overwrite the CLR dlls with the ones you've built locally. If you're a fan of the command line, here are some shell commands for doing this:
+
+```shell
+# Windows
+robocopy /e <coreclr path>\bin\Product\Windows_NT.<arch>.Debug <app root>\bin\Release\netcoreapp1.0\<rid>\publish > NUL
+
+# Unix
+cp -rT <coreclr path>/bin/Product/<OS>.<arch>.Debug <app root>/bin/Release/netcoreapp1.0/<rid>/publish
+```
+
+* Set the configuration knobs you need (see below) and run your published app. The info you want should be dumped to stdout.
+
+Here's some sample output on my machine showing the disassembly for `InefficientJoin`:
+
+```asm
+G_M2530_IG01:
+ 55 push rbp
+ 4883EC40 sub rsp, 64
+ 488D6C2440 lea rbp, [rsp+40H]
+ 33C0 xor rax, rax
+ 488945F8 mov qword ptr [rbp-08H], rax
+ 488965E0 mov qword ptr [rbp-20H], rsp
+
+G_M2530_IG02:
+ 49BB60306927E5010000 mov r11, 0x1E527693060
+ 4D8B1B mov r11, gword ptr [r11]
+ 4C895DF8 mov gword ptr [rbp-08H], r11
+ 49BB200058F7FD7F0000 mov r11, 0x7FFDF7580020
+ 3909 cmp dword ptr [rcx], ecx
+ 41FF13 call gword ptr [r11]System.Collections.Generic.IEnumerable`1[__Canon][System.__Canon]:GetEnumerator():ref:this
+ 488945F0 mov gword ptr [rbp-10H], rax
+
+; ...
+```
+
+## Setting configuration variables
+
+The behavior of the JIT can be controlled via a number of configuration variables. These are declared in [inc/clrconfigvalues.h](https://github.com/dotnet/coreclr/blob/master/src/inc/clrconfigvalues.h). When used as an environment variable, the string name generally has “COMPlus_” prepended. When used as a registry value name, the configuration name is used directly.
+
+These can be set in one of three ways:
+
+* Setting the environment variable `COMPlus_<flagname>`. For example, the following will set the `JitDump` flag so that the compilation of all methods named ‘Main’ will be dumped:
+
+```shell
+# Windows
+set COMPlus_JitDump=Main
+
+# Unix
+export COMPlus_JitDump=Main
+```
+
+* *Windows-only:* Setting the registry key `HKCU\Software\Microsoft\.NETFramework`, Value `<flagName>`, type `REG_SZ` or `REG_DWORD` (depending on the flag).
+* *Windows-only:* Setting the registry key `HKLM\Software\Microsoft\.NETFramework`, Value `<flagName>`, type `REG_SZ` or `REG_DWORD` (depending on the flag).
+
+## Specifying method names
+
+The complete syntax for specifying a single method name (for a flag that takes a method name, such as `COMPlus_JitDump`) is:
+
+```
+[[<Namespace>.]<ClassName>::]<MethodName>[([<types>)]
+```
+
+For example
+
+```
+System.Object::ToString(System.Object)
+```
+
+The namespace, class name, and argument types are optional, and if they are not present, default to a wildcard. Thus stating:
+
+```
+Main
+```
+
+will match all methods named Main from any class and any number of arguments.
+
+<types> is a comma separated list of type names. Note that presently only the number of arguments and not the types themselves are used to distinguish methods. Thus, `Main(Foo, Bar)` and `Main(int, int)` will both match any main method with two arguments.
+
+The wildcard character ‘*’ can be used for <ClassName> and <MethodName>. In particular * by itself indicates every method.
+
+## Useful COMPlus variables
+
+Below are some of the most useful `COMPlus` variables. Where {method-list} is specified in the list below, you can supply a space-separated list of either fully-qualified or simple method names (the former is useful when running something that has many methods of the same name), or you can specific ‘*’ to mean all methods.
+
+* `COMPlus_JitDump`={method-list} – dump lots of useful information about what the JIT is doing. See [Reading a JitDump](../botr/ryujit-overview.md#reading-a-jitdump) for more on how to analyze this data.
+* `COMPlus_JitDisasm`={method-list} – dump a disassembly listing of each method.
+* `COMPlus_JitDiffableDasm` – set to 1 to tell the JIT to avoid printing things like pointer values that can change from one invocation to the next, so that the disassembly can be more easily compared.
+* `COMPlus_JitGCDump`={method-list} – dump the GC information.
+* `COMPlus_JitUnwindDump`={method-list} – dump the unwind tables.
+* `COMPlus_JitEHDump`={method-list} – dump the exception handling tables.
+* `COMPlus_JitTimeLogFile`={file name} – this specifies a log file to which timing information is written.
+* `COMPlus_JitTimeLogCsv`={file name} – this specifies a log file to which summary timing information can be written, in CSV form.
+
+See also: [CLR Configuration Knobs](../project-docs/clr-configuration-knobs.md)
+
+## Dumping native images
+
+If you followed the tutorial above and ran the sample app, you may be wondering why the disassembly for methods like `Substring` didn't show up in the output. This is because `Substring` lives in mscorlib, which (by default) is compiled ahead-of-time to a native image via [crossgen](../building/crossgen.md). Telling crossgen to dump the info works slightly differently.
+
+* First, perform a debug build of the native parts of the repo: `build skipmscorlib skiptests`.
+ * This should produce the binaries for crossgen in `bin/Product/<OS>.<arch>.Debug`.
+* Next, set the appropriate configuration knob for the info you want to dump. Usually, this is just the same as the corresponding JIT knob, except prefixed with `Ngen`; for example, to show the disassembly listing of a particular method you would `set COMPlus_NgenDisasm=Foo`.
+* Run crossgen on the assembly you want to dump: `crossgen MyLibrary.dll`
+ * If you want to see the output of crossgen specifically for mscorlib, invoke `build skipnative skiptests` from the repo root. The dumps should be written to a file in `bin/Logs` that you can just view.
diff --git a/Documentation/project-docs/clr-complus-conf-docgen.sh b/Documentation/project-docs/clr-complus-conf-docgen.sh
index ab1d3f6230..2ee3f9bfc0 100755
--- a/Documentation/project-docs/clr-complus-conf-docgen.sh
+++ b/Documentation/project-docs/clr-complus-conf-docgen.sh
@@ -62,7 +62,7 @@ GENERATEDTABLEINFO="This table is machine-generated from commit $COMMIT on ${DAT
read -r -d '' CLRCONFIGSECTIONCONTENTS << "EOF"
When using these configurations from environment variables, the variables need to have the `COMPlus_` prefix in their names. e.g. To set DumpJittedMethods to 1, add the environment variable `COMPlus_DumpJittedMethods=1`.
-See also [Dumps and Other Tools](../botr/ryujit-overview.md#dumps-and-other-tools) for more information.
+See also [Setting configuration variables](../building/viewing-jit-dumps.md#setting-configuration-variables) for more information.
Name | Description | Type | Class | Default Value | Flags
-----|-------------|------|-------|---------------|-------
diff --git a/Documentation/project-docs/clr-configuration-knobs.md b/Documentation/project-docs/clr-configuration-knobs.md
index 2669873953..63f094b8ee 100644
--- a/Documentation/project-docs/clr-configuration-knobs.md
+++ b/Documentation/project-docs/clr-configuration-knobs.md
@@ -14,11 +14,11 @@ System.Threading.ThreadPool.MaxThreads|Override MaxThreads for the ThreadPool wo
## Environment/Registry Configuration Knobs
-This table is machine-generated from commit ae2d2f3 on 04/20/16. It might be out of date.
+This table is machine-generated from commit 82ed770 on 05/31/16. It might be out of date.
When using these configurations from environment variables, the variables need to have the `COMPlus_` prefix in their names. e.g. To set DumpJittedMethods to 1, add the environment variable `COMPlus_DumpJittedMethods=1`.
-See also [Dumps and Other Tools](../botr/ryujit-overview.md#dumps-and-other-tools) for more information.
+See also [Setting configuration variables](../building/viewing-jit-dumps.md#setting-configuration-variables) for more information.
Name | Description | Type | Class | Default Value | Flags
-----|-------------|------|-------|---------------|-------
@@ -133,7 +133,6 @@ Name | Description | Type | Class | Default Value | Flags
`DbgTransportLogClass` | mask to control what is logged in DbgTransportLog | DWORD | INTERNAL | |
`DbgTransportProxyAddress` | allows specifying the transport proxy address | STRING | UNSUPPORTED | | REGUTIL_default
`DbgTrapOnSkip` | allows breaking when we skip a breakpoint | DWORD | INTERNAL | 0 | REGUTIL_default
-`DbgWaitForDebuggerAttach` | Makes CoreCLR wait for a managed debugger to attach on process start (1) or regular process start (0) | DWORD | UNSUPPORTED | 0 |
`DbgWaitTimeout` | specifies the timeout value for waits | DWORD | INTERNAL | 1 | REGUTIL_default
`DbgWFDETimeout` | specifies the timeout value for wait when waiting for a debug event | DWORD | UNSUPPORTED | 25 | REGUTIL_default
`RaiseExceptionOnAssert` | Raise a first chance (if set to 1) or second chance (if set to 2) exception on asserts. | DWORD | INTERNAL | 0 | REGUTIL_default