mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 04:18:43 +00:00
Fixed core dump.
Fixed test runner core dump handler. Implemented debug engine core dump handler. Added SendCoreDump calls for null reference, stack corruption and stack overflow exceptions.
This commit is contained in:
parent
63257e85ef
commit
4e5e505e81
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