Merge pull request #1031 from CosmosOS/coredump-fixes

Fixed core dump
This commit is contained in:
Charles Betros 2018-10-07 15:00:35 -05:00 committed by GitHub
commit 668debc3ab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 152 additions and 61 deletions

View file

@ -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)

View file

@ -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]
}

View 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);
}
}
}

View file

@ -165,7 +165,7 @@ namespace Cosmos.Debug.DebugConnectors
protected void PacketCoreDump(byte[] aPacket)
{
CmdCoreDump?.Invoke(aPacket.ToArray());
CmdCoreDump?.Invoke(CoreDump.FromStackArray(aPacket));
WaitForMessage();
}

View file

@ -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;

View file

@ -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;