NET Profilers and IL Rewriting - DDD Melbourne 2

Preview:

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.

Citation preview

.NET Profilers aren’t scary

shaun.wilde@commonvision.com.au shaun_wilde@hotmail.com@scubamunki

Email:Email:

Twitter:

Who am I?

shaun.wilde@commonvision.com.au shaun_wilde@hotmail.com@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

Recommended