mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-24 12:35:31 +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(
|
aDebugConnector.CmdNullReferenceOccurred = a => AbortTestAndLogError(
|
||||||
"Null Reference Exception occurred at: 0x" + a.ToString("X8"));
|
"Null Reference Exception occurred at: 0x" + a.ToString("X8"));
|
||||||
|
|
||||||
aDebugConnector.CmdCoreDump = b =>
|
aDebugConnector.CmdCoreDump = dump =>
|
||||||
{
|
{
|
||||||
string xCallStack = "";
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
OutputHandler.LogMessage("Core dump:");
|
OutputHandler.LogMessage("Core dump:");
|
||||||
string eax = "EAX = 0x" +
|
|
||||||
b[i + 3].ToString("X2") + b[i + 2].ToString("X2") +
|
string eax = "EAX = 0x" + dump.EAX.ToString("X8");
|
||||||
b[i + 0].ToString("X2") + b[i + 1].ToString("X2");
|
string ebx = "EBX = 0x" + dump.EBX.ToString("X8");
|
||||||
i += 4;
|
string ecx = "ECX = 0x" + dump.ECX.ToString("X8");
|
||||||
string ebx = "EBX = 0x" +
|
string edx = "EDX = 0x" + dump.EDX.ToString("X8");
|
||||||
b[i + 3].ToString("X2") + b[i + 2].ToString("X2") +
|
|
||||||
b[i + 0].ToString("X2") + b[i + 1].ToString("X2");
|
string edi = "EDI = 0x" + dump.EDI.ToString("X8");
|
||||||
i += 4;
|
string esi = "ESI = 0x" + dump.ESI.ToString("X8");
|
||||||
string ecx = "ECX = 0x" +
|
|
||||||
b[i + 3].ToString("X2") + b[i + 2].ToString("X2") +
|
string ebp = "EBP = 0x" + dump.EBP.ToString("X8");
|
||||||
b[i + 0].ToString("X2") + b[i + 1].ToString("X2");
|
string esp = "ESP = 0x" + dump.ESP.ToString("X8");
|
||||||
i += 4;
|
string eip = "EIP = 0x" + dump.EIP.ToString("X8");
|
||||||
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;
|
|
||||||
|
|
||||||
OutputHandler.LogMessage(eax + " " + ebx + " " + ecx + " " + edx);
|
OutputHandler.LogMessage(eax + " " + ebx + " " + ecx + " " + edx);
|
||||||
OutputHandler.LogMessage(edi + " " + esi);
|
OutputHandler.LogMessage(edi + " " + esi);
|
||||||
OutputHandler.LogMessage(ebp + " " + esp + " " + eip);
|
OutputHandler.LogMessage(ebp + " " + esp + " " + eip);
|
||||||
OutputHandler.LogMessage("");
|
OutputHandler.LogMessage("");
|
||||||
|
|
||||||
while (i < b.Length)
|
OutputHandler.LogMessage("Call stack:");
|
||||||
|
OutputHandler.LogMessage("");
|
||||||
|
|
||||||
|
while (dump.StackTrace.Count > 0)
|
||||||
{
|
{
|
||||||
string xAddress = "0x" +
|
var xAddress = "0x" + dump.StackTrace.Pop().ToString("X8");
|
||||||
b[i + 3].ToString("X2") + b[i + 2].ToString("X2") +
|
OutputHandler.LogMessage("at " + xAddress);
|
||||||
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 = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OutputHandler.LogMessage("");
|
||||||
};
|
};
|
||||||
|
|
||||||
if (RunWithGDB)
|
if (RunWithGDB)
|
||||||
|
|
|
||||||
|
|
@ -321,6 +321,8 @@ function SendStackCorruptionOccurred {
|
||||||
// pointer value
|
// pointer value
|
||||||
ESI = @.CallerEIP
|
ESI = @.CallerEIP
|
||||||
ComWrite32()
|
ComWrite32()
|
||||||
|
|
||||||
|
SendCoreDump()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input: Stack
|
// Input: Stack
|
||||||
|
|
@ -334,6 +336,8 @@ function SendStackOverflowOccurred {
|
||||||
// pointer value
|
// pointer value
|
||||||
ESI = @.CallerEIP
|
ESI = @.CallerEIP
|
||||||
ComWrite32()
|
ComWrite32()
|
||||||
|
|
||||||
|
SendCoreDump()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input: None
|
// Input: None
|
||||||
|
|
@ -361,6 +365,8 @@ function SendNullReferenceOccurred {
|
||||||
// pointer value
|
// pointer value
|
||||||
ESI = @.CallerEIP
|
ESI = @.CallerEIP
|
||||||
ComWrite32()
|
ComWrite32()
|
||||||
|
|
||||||
|
SendCoreDump()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input: Stack
|
// Input: Stack
|
||||||
|
|
@ -405,9 +411,9 @@ function SendCoreDump {
|
||||||
ECX = 36
|
ECX = 36
|
||||||
EAX = EBP
|
EAX = EBP
|
||||||
while EAX != 0 {
|
while EAX != 0 {
|
||||||
EBX = EAX - 4
|
EBX = [EAX + 4]
|
||||||
+EAX
|
+EBX
|
||||||
ECX = ECX + 4
|
ECX + 4
|
||||||
EAX = [EAX]
|
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)
|
protected void PacketCoreDump(byte[] aPacket)
|
||||||
{
|
{
|
||||||
CmdCoreDump?.Invoke(aPacket.ToArray());
|
CmdCoreDump?.Invoke(CoreDump.FromStackArray(aPacket));
|
||||||
WaitForMessage();
|
WaitForMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ namespace Cosmos.Debug.DebugConnectors
|
||||||
public Action<byte[]> CmdStack;
|
public Action<byte[]> CmdStack;
|
||||||
public Action<byte[]> CmdPong;
|
public Action<byte[]> CmdPong;
|
||||||
public Action<byte, byte, byte[]> CmdChannel;
|
public Action<byte, byte, byte[]> CmdChannel;
|
||||||
public Action<byte[]> CmdCoreDump;
|
public Action<CoreDump> CmdCoreDump;
|
||||||
public Action<UInt32> CmdStackCorruptionOccurred;
|
public Action<UInt32> CmdStackCorruptionOccurred;
|
||||||
public Action<UInt32> CmdStackOverflowOccurred;
|
public Action<UInt32> CmdStackOverflowOccurred;
|
||||||
public Action<UInt32> CmdInterruptOccurred;
|
public Action<UInt32> CmdInterruptOccurred;
|
||||||
|
|
|
||||||
|
|
@ -359,6 +359,7 @@ namespace Cosmos.VS.DebugEngine.AD7.Impl
|
||||||
mDbgConnector.CmdNullReferenceOccurred += DbgCmdNullReferenceOccurred;
|
mDbgConnector.CmdNullReferenceOccurred += DbgCmdNullReferenceOccurred;
|
||||||
mDbgConnector.CmdMessageBox += DbgCmdMessageBox;
|
mDbgConnector.CmdMessageBox += DbgCmdMessageBox;
|
||||||
mDbgConnector.CmdChannel += DbgCmdChannel;
|
mDbgConnector.CmdChannel += DbgCmdChannel;
|
||||||
|
mDbgConnector.CmdCoreDump += DbgCmdCoreDump;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DbgCmdChannel(byte aChannel, byte aCommand, byte[] aData)
|
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);
|
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)
|
internal AD7Process(Dictionary<string, string> aDebugInfo, EngineCallback aCallback, AD7Engine aEngine, IDebugPort2 aPort)
|
||||||
{
|
{
|
||||||
mCallback = aCallback;
|
mCallback = aCallback;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue