mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 04:18:43 +00:00
commit
668debc3ab
6 changed files with 152 additions and 61 deletions
|
|
@ -88,72 +88,37 @@ namespace Cosmos.TestRunner.Core
|
|||
aDebugConnector.CmdNullReferenceOccurred = a => AbortTestAndLogError(
|
||||
"Null Reference Exception occurred at: 0x" + a.ToString("X8"));
|
||||
|
||||
aDebugConnector.CmdCoreDump = b =>
|
||||
aDebugConnector.CmdCoreDump = dump =>
|
||||
{
|
||||
string xCallStack = "";
|
||||
int i = 0;
|
||||
|
||||
OutputHandler.LogMessage("Core dump:");
|
||||
string eax = "EAX = 0x" +
|
||||
b[i + 3].ToString("X2") + b[i + 2].ToString("X2") +
|
||||
b[i + 0].ToString("X2") + b[i + 1].ToString("X2");
|
||||
i += 4;
|
||||
string ebx = "EBX = 0x" +
|
||||
b[i + 3].ToString("X2") + b[i + 2].ToString("X2") +
|
||||
b[i + 0].ToString("X2") + b[i + 1].ToString("X2");
|
||||
i += 4;
|
||||
string ecx = "ECX = 0x" +
|
||||
b[i + 3].ToString("X2") + b[i + 2].ToString("X2") +
|
||||
b[i + 0].ToString("X2") + b[i + 1].ToString("X2");
|
||||
i += 4;
|
||||
string edx = "EDX = 0x" +
|
||||
b[i + 3].ToString("X2") + b[i + 2].ToString("X2") +
|
||||
b[i + 0].ToString("X2") + b[i + 1].ToString("X2");
|
||||
i += 4;
|
||||
string edi = "EDI = 0x" +
|
||||
b[i + 3].ToString("X2") + b[i + 2].ToString("X2") +
|
||||
b[i + 0].ToString("X2") + b[i + 1].ToString("X2");
|
||||
i += 4;
|
||||
string esi = "ESI = 0x" +
|
||||
b[i + 3].ToString("X2") + b[i + 2].ToString("X2") +
|
||||
b[i + 0].ToString("X2") + b[i + 1].ToString("X2");
|
||||
i += 4;
|
||||
string ebp = "EBP = 0x" +
|
||||
b[i + 3].ToString("X2") + b[i + 2].ToString("X2") +
|
||||
b[i + 0].ToString("X2") + b[i + 1].ToString("X2");
|
||||
i += 4;
|
||||
string eip = "EIP = 0x" +
|
||||
b[i + 3].ToString("X2") + b[i + 2].ToString("X2") +
|
||||
b[i + 0].ToString("X2") + b[i + 1].ToString("X2");
|
||||
i += 4;
|
||||
string esp = "ESP = 0x" +
|
||||
b[i + 3].ToString("X2") + b[i + 2].ToString("X2") +
|
||||
b[i + 0].ToString("X2") + b[i + 1].ToString("X2");
|
||||
i += 4;
|
||||
|
||||
string eax = "EAX = 0x" + dump.EAX.ToString("X8");
|
||||
string ebx = "EBX = 0x" + dump.EBX.ToString("X8");
|
||||
string ecx = "ECX = 0x" + dump.ECX.ToString("X8");
|
||||
string edx = "EDX = 0x" + dump.EDX.ToString("X8");
|
||||
|
||||
string edi = "EDI = 0x" + dump.EDI.ToString("X8");
|
||||
string esi = "ESI = 0x" + dump.ESI.ToString("X8");
|
||||
|
||||
string ebp = "EBP = 0x" + dump.EBP.ToString("X8");
|
||||
string esp = "ESP = 0x" + dump.ESP.ToString("X8");
|
||||
string eip = "EIP = 0x" + dump.EIP.ToString("X8");
|
||||
|
||||
OutputHandler.LogMessage(eax + " " + ebx + " " + ecx + " " + edx);
|
||||
OutputHandler.LogMessage(edi + " " + esi);
|
||||
OutputHandler.LogMessage(ebp + " " + esp + " " + eip);
|
||||
OutputHandler.LogMessage("");
|
||||
|
||||
while (i < b.Length)
|
||||
OutputHandler.LogMessage("Call stack:");
|
||||
OutputHandler.LogMessage("");
|
||||
|
||||
while (dump.StackTrace.Count > 0)
|
||||
{
|
||||
string xAddress = "0x" +
|
||||
b[i + 3].ToString("X2") + b[i + 2].ToString("X2") +
|
||||
b[i + 0].ToString("X2") + b[i + 1].ToString("X2");
|
||||
xCallStack += xAddress + " ";
|
||||
if ((i != 0) && (i % 12 == 0))
|
||||
{
|
||||
OutputHandler.LogMessage(xCallStack.Trim());
|
||||
xCallStack = "";
|
||||
}
|
||||
i += 4;
|
||||
}
|
||||
if (xCallStack != "")
|
||||
{
|
||||
OutputHandler.LogMessage(xCallStack.Trim());
|
||||
xCallStack = "";
|
||||
var xAddress = "0x" + dump.StackTrace.Pop().ToString("X8");
|
||||
OutputHandler.LogMessage("at " + xAddress);
|
||||
}
|
||||
|
||||
OutputHandler.LogMessage("");
|
||||
};
|
||||
|
||||
if (RunWithGDB)
|
||||
|
|
|
|||
|
|
@ -321,6 +321,8 @@ function SendStackCorruptionOccurred {
|
|||
// pointer value
|
||||
ESI = @.CallerEIP
|
||||
ComWrite32()
|
||||
|
||||
SendCoreDump()
|
||||
}
|
||||
|
||||
// Input: Stack
|
||||
|
|
@ -334,6 +336,8 @@ function SendStackOverflowOccurred {
|
|||
// pointer value
|
||||
ESI = @.CallerEIP
|
||||
ComWrite32()
|
||||
|
||||
SendCoreDump()
|
||||
}
|
||||
|
||||
// Input: None
|
||||
|
|
@ -361,6 +365,8 @@ function SendNullReferenceOccurred {
|
|||
// pointer value
|
||||
ESI = @.CallerEIP
|
||||
ComWrite32()
|
||||
|
||||
SendCoreDump()
|
||||
}
|
||||
|
||||
// Input: Stack
|
||||
|
|
@ -405,9 +411,9 @@ function SendCoreDump {
|
|||
ECX = 36
|
||||
EAX = EBP
|
||||
while EAX != 0 {
|
||||
EBX = EAX - 4
|
||||
+EAX
|
||||
ECX = ECX + 4
|
||||
EBX = [EAX + 4]
|
||||
+EBX
|
||||
ECX + 4
|
||||
EAX = [EAX]
|
||||
}
|
||||
|
||||
|
|
|
|||
59
source/Cosmos.Debug.DebugConnectors/CoreDump.cs
Normal file
59
source/Cosmos.Debug.DebugConnectors/CoreDump.cs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Cosmos.Debug.DebugConnectors
|
||||
{
|
||||
public class CoreDump
|
||||
{
|
||||
public uint EAX { get; }
|
||||
public uint EBX { get; }
|
||||
public uint ECX { get; }
|
||||
public uint EDX { get; }
|
||||
|
||||
public uint ESI { get; }
|
||||
public uint EDI { get; }
|
||||
|
||||
public uint EBP { get; }
|
||||
public uint ESP { get; }
|
||||
public uint EIP { get; }
|
||||
|
||||
public Stack<uint> StackTrace { get; }
|
||||
|
||||
public CoreDump(
|
||||
uint eax, uint ebx, uint ecx, uint edx,
|
||||
uint esi, uint edi,
|
||||
uint ebp, uint esp, uint eip,
|
||||
Stack<uint> stackTrace)
|
||||
{
|
||||
EAX = eax;
|
||||
EBX = ebx;
|
||||
ECX = ecx;
|
||||
EDX = edx;
|
||||
|
||||
ESI = esi;
|
||||
EDI = edi;
|
||||
|
||||
EBP = ebp;
|
||||
ESP = esp;
|
||||
EIP = eip;
|
||||
|
||||
StackTrace = stackTrace;
|
||||
}
|
||||
|
||||
internal static CoreDump FromStackArray(byte[] stackBytes)
|
||||
{
|
||||
var stack = new Stack<uint>(stackBytes.Length / 4);
|
||||
|
||||
for (int i = 0; i < stackBytes.Length; i += 4)
|
||||
{
|
||||
stack.Push(BitConverter.ToUInt32(stackBytes, i));
|
||||
}
|
||||
|
||||
return new CoreDump(
|
||||
stack.Pop(), stack.Pop(), stack.Pop(), stack.Pop(),
|
||||
stack.Pop(), stack.Pop(),
|
||||
stack.Pop(), stack.Pop(), stack.Pop(),
|
||||
stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -165,7 +165,7 @@ namespace Cosmos.Debug.DebugConnectors
|
|||
|
||||
protected void PacketCoreDump(byte[] aPacket)
|
||||
{
|
||||
CmdCoreDump?.Invoke(aPacket.ToArray());
|
||||
CmdCoreDump?.Invoke(CoreDump.FromStackArray(aPacket));
|
||||
WaitForMessage();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ namespace Cosmos.Debug.DebugConnectors
|
|||
public Action<byte[]> CmdStack;
|
||||
public Action<byte[]> CmdPong;
|
||||
public Action<byte, byte, byte[]> CmdChannel;
|
||||
public Action<byte[]> CmdCoreDump;
|
||||
public Action<CoreDump> CmdCoreDump;
|
||||
public Action<UInt32> CmdStackCorruptionOccurred;
|
||||
public Action<UInt32> CmdStackOverflowOccurred;
|
||||
public Action<UInt32> CmdInterruptOccurred;
|
||||
|
|
|
|||
|
|
@ -359,6 +359,7 @@ namespace Cosmos.VS.DebugEngine.AD7.Impl
|
|||
mDbgConnector.CmdNullReferenceOccurred += DbgCmdNullReferenceOccurred;
|
||||
mDbgConnector.CmdMessageBox += DbgCmdMessageBox;
|
||||
mDbgConnector.CmdChannel += DbgCmdChannel;
|
||||
mDbgConnector.CmdCoreDump += DbgCmdCoreDump;
|
||||
}
|
||||
|
||||
private void DbgCmdChannel(byte aChannel, byte aCommand, byte[] aData)
|
||||
|
|
@ -407,6 +408,66 @@ namespace Cosmos.VS.DebugEngine.AD7.Impl
|
|||
AD7Util.MessageBox("Message from your Cosmos operating system:\r\n\r\n" + message);
|
||||
}
|
||||
|
||||
private void DbgCmdCoreDump(CoreDump dump)
|
||||
{
|
||||
var eax = GetRegister("EAX", dump.EAX);
|
||||
var ebx = GetRegister("EBX", dump.EBX);
|
||||
var ecx = GetRegister("ECX", dump.ECX);
|
||||
var edx = GetRegister("EDX", dump.EDX);
|
||||
|
||||
var edi = GetRegister("EDI", dump.EDI);
|
||||
var esi = GetRegister("ESI", dump.ESI);
|
||||
|
||||
var ebp = GetRegister("EBP", dump.EBP);
|
||||
var esp = GetRegister("ESP", dump.ESP);
|
||||
var eip = GetRegister("EIP", dump.EIP);
|
||||
|
||||
var message = "Core dump:" + Environment.NewLine
|
||||
+ $"{eax} {ebx} {ecx} {edx}" + Environment.NewLine
|
||||
+ $"{edi} {esi}" + Environment.NewLine
|
||||
+ $"{ebp} {esp} {eip}" + Environment.NewLine
|
||||
+ Environment.NewLine
|
||||
+ "Call stack:"
|
||||
+ Environment.NewLine;
|
||||
|
||||
while (dump.StackTrace.Count > 0)
|
||||
{
|
||||
message += GetStackTraceEntry(dump.StackTrace.Pop()) + Environment.NewLine;
|
||||
}
|
||||
|
||||
AD7Util.MessageBox(message);
|
||||
|
||||
string GetRegister(string name, uint value) => $"{name} = 0x{value:X8}";
|
||||
|
||||
string GetStackTraceEntry(uint address)
|
||||
{
|
||||
var entry = $"at 0x{address:X8}";
|
||||
|
||||
if (mDebugInfo.TryGetValue(BuildPropertyNames.DebugModeString, out var xDebugMode))
|
||||
{
|
||||
if (xDebugMode == "Source")
|
||||
{
|
||||
try
|
||||
{
|
||||
var xMethod = mDebugInfoDb.GetMethod(address);
|
||||
var xDocument = mDebugInfoDb.GetDocumentById(xMethod.DocumentID);
|
||||
var xLabel = mDebugInfoDb.GetLabels(address)[0];
|
||||
var xMethodIlOp = mDebugInfoDb.TryGetFirstMethodIlOpByLabelName(xLabel.Remove(xLabel.LastIndexOf('.'))).IlOffset;
|
||||
var xSequencePoints = mDebugInfoDb.GetSequencePoints(mDebugInfoDb.GetAssemblyFileById(xMethod.AssemblyFileID).Pathname, xMethod.MethodToken);
|
||||
var xLine = xSequencePoints.Where(q => q.Offset <= xMethodIlOp).Last().LineStart;
|
||||
|
||||
entry += $"in {xDocument.Pathname}:line {xLine}";
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
internal AD7Process(Dictionary<string, string> aDebugInfo, EngineCallback aCallback, AD7Engine aEngine, IDebugPort2 aPort)
|
||||
{
|
||||
mCallback = aCallback;
|
||||
|
|
|
|||
Loading…
Reference in a new issue