net profilers and il rewriting - ddd melbourne 2
DESCRIPTION
A presentation on writing your own .NET profiler to use for IL rewriting as presented at DDD Melbourne 2.Uses ATL (C++) and code from OpenCover.TRANSCRIPT
Who am I?
[email protected] [email protected]@scubamunki
Email:Email:
Twitter:
Specialize in providing project teams with the necessary frameworks and personnel during the critical early stages of the project.
CoverageEye.NET◦ Originally hosted on GotDotNet
PartCover◦ Originally hosted on SourceForge◦ Forked to GitHub
https://github.com/sawilde/partcover.net4
OpenCover◦ Hosted on GitHub
https://github.com/sawilde/opencover
How did I get here?
Profilers: What are they good for?◦ Quick review of some commercial and open
source .NET profilers Overview of the profiler API Code and Demos Basics of IL rewriting Code and Demos II Introducing new classes and methods Code and Demos III Extras (If time permits)
.NET Profilers aren’t (that) scary
Profilers: What are they good for?
Monitor Load/Unload Events◦ Application Domains◦ Assemblies◦ Modules◦ Classes
JIT Compilation Events Monitor threads, remoting and
native/managed transitions Monitor GC events Monitor exceptions Monitor method enter/leave
Monitor the runtime
Get the names and signatures of classes and methods
Read the IL for methods (functions) Memory allocations
◦ Types◦ Garbage Collection
Call graphs
Interrogate the runtime
Dynamically create new classes and methods
Rewrite the IL of existing methods Allocate memory Work with the GC
Interact with the runtime
Commercial
Redgate ANTS
NCover (was originally Open Source)
JetBrains dotCover/dotTrace
CLRProfiler4 (Microsoft with Source Code)
Commercial and Open Source Profilers*
(*Obviously this list is not complete)
Open Source
Nprof http://code.google.com/p/nprof/
SlimTune http://code.google.com/p/slimtune/
PartCover https://github.com/sawilde/partcover.net4
OpenCover https://github.com/sawilde/opencover
Commercial and Open Source Profilers*
(*Obviously this list is not complete)
System.Reflection.Emit◦ .NET Framework
Mono.Cecil◦ https://github.com/mono/cecil
Other IL (Re)Writing Methods
Important Interfaces Implementation and Registration
Overview of the Profiler API
In-process COM object◦ i.e. a DLL
Native code◦ i.e. unmanaged code
Free threaded◦ i.e. the developer is responsible for any required
synchronisation 32/64 bit
◦ Like for like
Implementation
I Cor Pr ofi l er I nf o2/ 3
I Unknown
Runt i me
I Cor Pr ofi l er Cal l back2/ 3
I Unknown
Pr ofi l er
Tar get Appl i cat i on
Launchi ng Appl i cat i onCOR_ENABLE_PROFI LI NG=1
COR_PROFI LER=<CLSI D or PROGI D of Pr ofi l er >
Cust om Appl i cat i on
Command Li ne
.NET Runtime through the ages
ICorProfilerCallback◦ 69 Methods
ICorProfilerInfo◦ 33 Methods
IMetaDataImport◦ 64 Methods
IMetaDataEmit◦ 49 Methods
.NET1
ICorProfilerCallback2◦ 8 Methods
ICorProfilerInfo2◦ 21 Methods
IMetaDataImport2◦ 64 Methods
IMetaDataEmit2◦ 49 Methods
.NET2
ICorProfilerCallback3◦ 3 Methods
ICorProfilerInfo3◦ 14 Methods
.NET4
Methods
How much?
Register the COM Object
Use Environment variables
c:>set COR_ENABLE_PROFILING=1c:>set COR_PROFILER=MyProfiler.Profiler
Instantiation
NET4 profilers can be used to profile .NET2 assemblies
Need to be side-by-side CLR awarePick onePick firstPick all/many
◦ RunSxS http://archive.msdn.microsoft.com/RunSxS
.NET4
Silverlight support
CORECLR_ENABLE_PROFILINGCORECLR_PROFILERCORECLR_PROFILER_PATH
.NET4
Creating an ATL COM object with required interfaces
Demo 1
Create host and target processes
Launch Target with Profiler
Simple Target
Demo 2
Requesting and handling events◦ ICorProfilerInfo::SetEventMask
COR_PRF_MONITOR_MODULE_LOADS
COR_PRF_MONITOR_JIT_COMPILATION
COR_PRF_DISABLE_INLINING
COR_PRF_DISABLE_OPTIMIZATIONS
Demo 3
Getting assembly and method names
Interfaces◦ ICorProfilerInfo3◦ IMetaDataImport2
Demo 4
What is a Method?◦ Headers◦ Sections◦ Clauses
The Method Body◦ Operations◦ Branches◦ The Stack◦ Debug vs. Release
Basics of IL Rewriting
Tiny and Fat Methods
1 0
CODE SIZE TYPE
Method with Tiny Header
HEAD
ERM
ETHO
DSECTIO
NS
Method with Fat Header
*
CODE SIZE
TYPE
LOCAL VARIABLES SIGNATURE TOKEN
HEADER SIZE FLAGS
0 0 1 1 * 1 1
MAX STACK
MO
RE SECTION
S
INITIALIZE LO
CAL VARIABLES
Tiny and Fat Sections
EH TABLE
FAT FO
RMAT
MO
RE SECTIO
NS
* 0 1
KINDDATA SIZE RESERVED
Tiny Section
EH TABLE
FAT FO
RMAT
MO
RE SECTIO
NS
* 1 1
KIND DATA SIZE
Fat Section
Tiny and Fat Clauses
FLAGS
TRY OFFSET
TRY LENGTH
HANDLEROFFSET
HANDLERLENGTH
CLASSTOKEN/OFFSET
TINY CLAUSE
FLAGS
TRY OFFSET
TRY LENGTH
HANDLEROFFSET
HANDLERLENGTH
CLASSTOKEN/OFFSET
FAT CLAUSE
5 Types of Clauses◦ COR_ILEXCEPTION_CLAUSE_NONE◦ COR_ILEXCEPTION_CLAUSE_FILTER◦ COR_ILEXCEPTION_CLAUSE_FINALLY◦ COR_ILEXCEPTION_CLAUSE_FAULT◦ COR_ILEXCEPTION_CLAUSE_DUPLICATED
Clauses
Try/Catch Code in handler block is called if an
exception of the type expected is thrown from code that is contained in the try block. (needs rewording)
COR_ILEXCEPTION_CLAUSE_NONE
Variation on Try/Catch VB.NET only
COR_ILEXCEPTION_CLAUSE_FILTER
Try/Finally Code in handler block always called
regardless of how the associated try block is exited.
COR_ILEXCEPTION_CLAUSE_FINALLY
Try/Fault Code in handler block is only called if an
exception has occurred in the corresponding try block.
The exception continues on… IL Only?
COR_ILEXCEPTION_CLAUSE_FAULT
A Mystery
// duplicated clause.. this clause was duplicated down to a funclet which was pulled out of line
COR_ILEXCEPTION_CLAUSE_DUPLICATED
The Method Body◦ Operations◦ Branches◦ The Stack◦ Debug vs. Release
The Method Body
Contains all the information needed to interpret and write IL◦ Canonical Name◦ String Name◦ Stack Behaviour◦ Parameter Size◦ Length◦ Bytes◦ Control Flow
OPCODE.DEF
OPCODE.DEF
OPCODE.DEF
Is there a difference?
Debug vs. Release
Headers◦ Stack size◦ Method Size
Clauses◦ Offsets◦ Lengths
Branches◦ Size of Jump
Considerations when adding IL
Make …◦ Tiny headers Fat◦ Tiny sections Fat◦ Tiny clauses Fat◦ Short branches Long
Cheat…◦ Use the parser from OpenCover
Common approach when adding IL
Leverage the OpenCover parser
Demo 5
Add a new Type◦ Exception◦ Define Constructor (.ctor)
Throw new Type◦ Add extra IL to TargetMethod
Adding new classes and methods I
Interfaces◦ IMetaDataEmit2◦ IMetaDataAssemblyEmit
Adding New Classes and Methods
IL DASM
Complicated Intensive
Hmmmm……
Sequence Points◦ PDB Files
IL Rewriting◦ Points out of sync
Debugging
The End
Demo code◦ https://github.com/sawilde/DDD2011_ProfilerDemo