/*private void CorProcess_OnStepComplete(object sender, CorStepCompleteEventArgs e) { // if (iCount++ % 100 == 0 && logOnBreakpoint) DI.log.info("[{0}] CorProcess_OnStepComplete {1}", iStepCount++, getActiveFrameFunctionName(e)); e.Continue = handleDebugFlowAction(); } private void CorProcess_OnBreakpointSetError(object sender, CorBreakpointEventArgs e) { if (logOnBreakpoint) DI.log.info("CorProcess_OnBreakpointSetError {0}", getActiveFrameFunctionName(e)); e.Continue = true; } private void CorProcess_OnBreakpoint(object sender, CorBreakpointEventArgs e) { DI.log.info("in CorProcess_OnBreakpoint"); /*( if (handleBreakpoints) { if (logOnBreakpoint) log.info("Breakpoint on {0}", getActiveFrameFunctionName(e)); e.Continue = handleDebugFlowAction(); }* / e.Continue = true; } private bool handleDebugFlowAction() { switch (onBreakPointAction) { case OnBreakPointAction.StepOut: o2MDbgOLD.mdbgProcess.StepOut(); break; case OnBreakPointAction.StepInto: o2MDbgOLD.mdbgProcess.StepInto(false); break; case OnBreakPointAction.StepOver: o2MDbgOLD.mdbgProcess.StepOver(false); break; case OnBreakPointAction.Stop: return false; case OnBreakPointAction.Continue: return true; } return true; } */ public static string getActiveFrameFunctionName(CorEventArgs e) { try { if (e.Thread.ActiveFrame == null) return "e.Thread.ActiveFrame == null"; //var corFunctionBreakpoint = (CorFunctionBreakpoint)e.Breakpoint; var corMetadataImport = new CorMetadataImport(e.Thread.ActiveFrame.Function.Class.Module); MethodInfo methodInfo = corMetadataImport.GetMethodInfo(e.Thread.ActiveFrame.Function.Token); return (methodInfo.DeclaringType.FullName ?? "(null)") + " :: " + (methodInfo.Name ?? "(null)"); } catch (Exception ex) { DI.log.ex(ex, "getActiveFrameFunctionName"); return ""; } }
public static void Disassemble(byte[] ilCode, CorMetadataImport importer, out string[] lines, out int[] ip2line) { var ils = new ArrayList(); ip2line = new int[ilCode.Length]; int pc = 0; while (pc < ilCode.Length) { string instruction = ""; int instruction_start = pc; int opCodeSize; ILOpCode opCode = DecodeOpcode(ilCode, pc, out opCodeSize); pc += opCodeSize; switch ((OpcodeFormat) GenTables.opCodeTypeInfo[(int) opCode].Type) { default: Debug.Assert(false); break; case OpcodeFormat.InlineNone: instruction = GenTables.opCodeTypeInfo[(int) opCode].Name; break; case OpcodeFormat.ShortInlineI: case OpcodeFormat.ShortInlineVar: { byte arg = ilCode[pc]; pc++; instruction = String.Format(CultureInfo.InvariantCulture, "{0} {1}", new Object[] { GenTables. opCodeTypeInfo [ (int) opCode]. Name, arg }); break; } case OpcodeFormat.InlineVar: { Int16 arg; unsafe { fixed (byte* i = &(ilCode[pc])) arg = *(Int16*) i; } pc += 2; instruction = String.Format(CultureInfo.InvariantCulture, "{0} {1}", new Object[] { GenTables. opCodeTypeInfo [ (int) opCode]. Name, arg }); break; } case OpcodeFormat.InlineI: case OpcodeFormat.InlineRVA: { Int32 arg; unsafe { fixed (byte* i = &(ilCode[pc])) arg = *(Int32*) i; } pc += 4; instruction = String.Format(CultureInfo.InvariantCulture, "{0} {1}", new Object[] { GenTables. opCodeTypeInfo [ (int) opCode]. Name, arg }); break; } case OpcodeFormat.InlineI8: { Int64 arg; unsafe { fixed (byte* i = &(ilCode[pc])) arg = *(Int64*) i; } pc += 8; instruction = String.Format(CultureInfo.InvariantCulture, "{0} {1}", new Object[] { GenTables. opCodeTypeInfo [ (int) opCode]. Name, arg }); break; } case OpcodeFormat.ShortInlineR: { float arg; unsafe { fixed (byte* i = &(ilCode[pc])) arg = *(float*) i; } pc += 4; instruction = String.Format(CultureInfo.InvariantCulture, "{0} {1}", new Object[] { GenTables. opCodeTypeInfo [ (int) opCode]. Name, arg }); break; } case OpcodeFormat.InlineR: { double arg; unsafe { fixed (byte* i = &(ilCode[pc])) arg = *(double*) i; } pc += 8; instruction = String.Format(CultureInfo.InvariantCulture, "{0} {1}", new Object[] { GenTables. opCodeTypeInfo [ (int) opCode]. Name, arg }); break; } case OpcodeFormat.ShortInlineBrTarget: { var offset = (sbyte) ilCode[pc]; pc++; int dest = pc + offset; instruction = String.Format(CultureInfo.InvariantCulture, "{0} IL_{1,-4:X}", new Object[] { GenTables . opCodeTypeInfo [ ( int ) opCode ]. Name , dest }); break; } case OpcodeFormat.InlineBrTarget: { Int32 offset; unsafe { fixed (byte* i = &(ilCode[pc])) offset = *(Int32*) i; } pc += 4; int dest = pc + offset; instruction = String.Format(CultureInfo.InvariantCulture, "{0} IL_{1,-4:X}", new Object[] { GenTables . opCodeTypeInfo [ ( int ) opCode ]. Name , dest }); break; } case OpcodeFormat.InlineSwitch: case OpcodeFormat.InlinePhi: instruction = "MESSED UP!"; // variable size Debug.Assert(false); break; case OpcodeFormat.InlineString: case OpcodeFormat.InlineField: case OpcodeFormat.InlineType: case OpcodeFormat.InlineToken: case OpcodeFormat.InlineMethod: { int token; unsafe { fixed (byte* i = &(ilCode[pc])) { token = *(Int32*) i; } } pc += 4; CorTokenType tokenType = TokenUtils.TypeFromToken(token); // if it is reference token we need to dereference it. string arg = null; switch (tokenType) { default: Debug.Assert(false); break; case CorTokenType.mdtTypeDef: int extendsToken; arg = importer.GetTypeNameFromDef(token, out extendsToken); break; case CorTokenType.mdtTypeRef: arg = importer.GetTypeNameFromRef(token); break; case CorTokenType.mdtTypeSpec: arg = "NYI"; break; case CorTokenType.mdtMethodDef: MethodInfo mi = importer.GetMethodInfo(token); Type dt = mi.DeclaringType; arg = (dt == null ? "" : dt.Name) + "." + mi.Name; break; case CorTokenType.mdtFieldDef: arg = "NYI"; break; case CorTokenType.mdtMemberRef: arg = importer.GetMemberRefName(token); break; case CorTokenType.mdtString: arg = "\"" + importer.GetUserString(token) + "\""; break; } // switch(tokenType) instruction = String.Format(CultureInfo.InvariantCulture, "{0} {1}", new Object[] { GenTables. opCodeTypeInfo [ (int) opCode]. Name, arg }); break; } case OpcodeFormat.InlineSig: instruction = GenTables.opCodeTypeInfo[(int) opCode].Name; pc += 4; break; } // switch((OpcodeFormat)GenTables.opCodeTypeInfo[(int)opCode].Type) ils.Add(String.Format(CultureInfo.InvariantCulture, "IL_{0,-4:X}: {1}", new Object[] {instruction_start, instruction})); // add ip2line mapping for (int i = instruction_start; i < pc; i++) ip2line[i] = ils.Count - 1; // last line } // while(pc<ilCode.Length) lines = (string[]) ils.ToArray(typeof (string)); return; }