Print Guest Stack Trace in ServiceNotImplemented Exception (#650)

* Print Guest Stack Trace in ServiceNotImplemented Exception

* Remove PrintGuestStackTrace

* Print Process Name and PID at the start of guest stack trace
This commit is contained in:
jduncanator 2019-03-15 14:37:54 +11:00 committed by GitHub
parent 1bef70c068
commit efebd8f94d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 76 additions and 47 deletions

View file

@ -76,60 +76,70 @@ namespace Ryujinx.HLE.Exceptions
} }
} }
sb.AppendLine("Guest Stack Trace:");
sb.AppendLine(Context.Thread.GetGuestStackTrace());
// Print buffer information // Print buffer information
sb.AppendLine("Buffer Information"); if (Request.PtrBuff.Count > 0 ||
Request.SendBuff.Count > 0 ||
if (Request.PtrBuff.Count > 0) Request.ReceiveBuff.Count > 0 ||
Request.ExchangeBuff.Count > 0 ||
Request.RecvListBuff.Count > 0)
{ {
sb.AppendLine("\tPtrBuff:"); sb.AppendLine("Buffer Information:");
foreach (var buff in Request.PtrBuff) if (Request.PtrBuff.Count > 0)
{ {
sb.AppendLine($"\t[{buff.Index}] Position: 0x{buff.Position:x16} Size: 0x{buff.Size:x16}"); sb.AppendLine("\tPtrBuff:");
foreach (var buff in Request.PtrBuff)
{
sb.AppendLine($"\t[{buff.Index}] Position: 0x{buff.Position:x16} Size: 0x{buff.Size:x16}");
}
} }
}
if (Request.SendBuff.Count > 0) if (Request.SendBuff.Count > 0)
{
sb.AppendLine("\tSendBuff:");
foreach (var buff in Request.SendBuff)
{ {
sb.AppendLine($"\tPosition: 0x{buff.Position:x16} Size: 0x{buff.Size:x16} Flags: {buff.Flags}"); sb.AppendLine("\tSendBuff:");
foreach (var buff in Request.SendBuff)
{
sb.AppendLine($"\tPosition: 0x{buff.Position:x16} Size: 0x{buff.Size:x16} Flags: {buff.Flags}");
}
} }
}
if (Request.ReceiveBuff.Count > 0) if (Request.ReceiveBuff.Count > 0)
{
sb.AppendLine("\tReceiveBuff:");
foreach (var buff in Request.ReceiveBuff)
{ {
sb.AppendLine($"\tPosition: 0x{buff.Position:x16} Size: 0x{buff.Size:x16} Flags: {buff.Flags}"); sb.AppendLine("\tReceiveBuff:");
foreach (var buff in Request.ReceiveBuff)
{
sb.AppendLine($"\tPosition: 0x{buff.Position:x16} Size: 0x{buff.Size:x16} Flags: {buff.Flags}");
}
} }
}
if (Request.ExchangeBuff.Count > 0) if (Request.ExchangeBuff.Count > 0)
{
sb.AppendLine("\tExchangeBuff:");
foreach (var buff in Request.ExchangeBuff)
{ {
sb.AppendLine($"\tPosition: 0x{buff.Position:x16} Size: 0x{buff.Size:x16} Flags: {buff.Flags}"); sb.AppendLine("\tExchangeBuff:");
foreach (var buff in Request.ExchangeBuff)
{
sb.AppendLine($"\tPosition: 0x{buff.Position:x16} Size: 0x{buff.Size:x16} Flags: {buff.Flags}");
}
} }
}
if (Request.RecvListBuff.Count > 0) if (Request.RecvListBuff.Count > 0)
{
sb.AppendLine("\tRecvListBuff:");
foreach (var buff in Request.RecvListBuff)
{ {
sb.AppendLine($"\tPosition: 0x{buff.Position:x16} Size: 0x{buff.Size:x16}"); sb.AppendLine("\tRecvListBuff:");
}
}
sb.AppendLine(); foreach (var buff in Request.RecvListBuff)
{
sb.AppendLine($"\tPosition: 0x{buff.Position:x16} Size: 0x{buff.Size:x16}");
}
}
sb.AppendLine();
}
sb.AppendLine("Raw Request Data:"); sb.AppendLine("Raw Request Data:");
sb.Append(HexUtils.HexTable(Request.RawData)); sb.Append(HexUtils.HexTable(Request.RawData));

View file

@ -2,6 +2,7 @@ using ChocolArm64.Memory;
using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Ipc; using Ryujinx.HLE.HOS.Kernel.Ipc;
using Ryujinx.HLE.HOS.Kernel.Process; using Ryujinx.HLE.HOS.Kernel.Process;
using Ryujinx.HLE.HOS.Kernel.Threading;
using System; using System;
using System.IO; using System.IO;
@ -13,6 +14,7 @@ namespace Ryujinx.HLE.HOS.Ipc
Switch device, Switch device,
KProcess process, KProcess process,
MemoryManager memory, MemoryManager memory,
KThread thread,
KClientSession session, KClientSession session,
IpcMessage request, IpcMessage request,
long cmdPtr) long cmdPtr)
@ -36,6 +38,7 @@ namespace Ryujinx.HLE.HOS.Ipc
device, device,
process, process,
memory, memory,
thread,
session, session,
request, request,
response, response,

View file

@ -4,6 +4,7 @@ using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Diagnostics.Demangler; using Ryujinx.HLE.HOS.Diagnostics.Demangler;
using Ryujinx.HLE.HOS.Kernel.Memory; using Ryujinx.HLE.HOS.Kernel.Memory;
using Ryujinx.HLE.Loaders.Elf; using Ryujinx.HLE.Loaders.Elf;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -41,14 +42,12 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
_images = new List<Image>(); _images = new List<Image>();
} }
public void PrintGuestStackTrace(CpuThreadState threadState) public string GetGuestStackTrace(CpuThreadState threadState)
{ {
EnsureLoaded(); EnsureLoaded();
StringBuilder trace = new StringBuilder(); StringBuilder trace = new StringBuilder();
trace.AppendLine("Guest stack trace:");
void AppendTrace(long address) void AppendTrace(long address)
{ {
Image image = GetImage(address, out int imageIndex); Image image = GetImage(address, out int imageIndex);
@ -68,22 +67,22 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
string imageName = GetGuessedNsoNameFromIndex(imageIndex); string imageName = GetGuessedNsoNameFromIndex(imageIndex);
string imageNameAndOffset = $"[{_owner.Name}] {imageName}:0x{offset:x8}"; trace.AppendLine($" {imageName}:0x{offset:x8} {subName}");
trace.AppendLine($" {imageNameAndOffset} {subName}");
} }
else else
{ {
trace.AppendLine($" [{_owner.Name}] ??? {subName}"); trace.AppendLine($" ??? {subName}");
} }
} }
//TODO: ARM32. //TODO: ARM32.
long framePointer = (long)threadState.X29; long framePointer = (long)threadState.X29;
trace.AppendLine($"Process: {_owner.Name}, PID: {_owner.Pid}");
while (framePointer != 0) while (framePointer != 0)
{ {
if ((framePointer & 7) != 0 || if ((framePointer & 7) != 0 ||
!_owner.CpuMemory.IsMapped(framePointer) || !_owner.CpuMemory.IsMapped(framePointer) ||
!_owner.CpuMemory.IsMapped(framePointer + 8)) !_owner.CpuMemory.IsMapped(framePointer + 8))
{ {
@ -97,7 +96,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
framePointer = _owner.CpuMemory.ReadInt64(framePointer); framePointer = _owner.CpuMemory.ReadInt64(framePointer);
} }
Logger.PrintInfo(LogClass.Cpu, trace.ToString()); return trace.ToString();
} }
private bool TryGetSubName(Image image, long address, out string name) private bool TryGetSubName(Image image, long address, out string name)

View file

@ -143,6 +143,7 @@ namespace Ryujinx.HLE.HOS.Kernel.SupervisorCall
_device, _device,
_process, _process,
_process.CpuMemory, _process.CpuMemory,
ipcMessage.Thread,
ipcMessage.Session, ipcMessage.Session,
ipcMessage.Message, ipcMessage.Message,
ipcMessage.MessagePtr); ipcMessage.MessagePtr);

View file

@ -1,10 +1,12 @@
using ChocolArm64; using ChocolArm64;
using ChocolArm64.Memory; using ChocolArm64.Memory;
using Ryujinx.Common.Logging;
using Ryujinx.HLE.HOS.Kernel.Common; using Ryujinx.HLE.HOS.Kernel.Common;
using Ryujinx.HLE.HOS.Kernel.Process; using Ryujinx.HLE.HOS.Kernel.Process;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
namespace Ryujinx.HLE.HOS.Kernel.Threading namespace Ryujinx.HLE.HOS.Kernel.Threading
{ {
@ -1009,9 +1011,19 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
ReleaseAndResume(); ReleaseAndResume();
} }
public string GetGuestStackTrace()
{
return Owner.Debugger.GetGuestStackTrace(Context.ThreadState);
}
public void PrintGuestStackTrace() public void PrintGuestStackTrace()
{ {
Owner.Debugger.PrintGuestStackTrace(Context.ThreadState); StringBuilder trace = new StringBuilder();
trace.AppendLine("Guest stack trace:");
trace.AppendLine(GetGuestStackTrace());
Logger.PrintInfo(LogClass.Cpu, trace.ToString());
} }
private void ThreadFinishedHandler(object sender, EventArgs e) private void ThreadFinishedHandler(object sender, EventArgs e)

View file

@ -2,6 +2,7 @@ using ChocolArm64.Memory;
using Ryujinx.HLE.HOS.Ipc; using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Ipc; using Ryujinx.HLE.HOS.Kernel.Ipc;
using Ryujinx.HLE.HOS.Kernel.Process; using Ryujinx.HLE.HOS.Kernel.Process;
using Ryujinx.HLE.HOS.Kernel.Threading;
using System.IO; using System.IO;
namespace Ryujinx.HLE.HOS namespace Ryujinx.HLE.HOS
@ -11,6 +12,7 @@ namespace Ryujinx.HLE.HOS
public Switch Device { get; } public Switch Device { get; }
public KProcess Process { get; } public KProcess Process { get; }
public MemoryManager Memory { get; } public MemoryManager Memory { get; }
public KThread Thread { get; }
public KClientSession Session { get; } public KClientSession Session { get; }
public IpcMessage Request { get; } public IpcMessage Request { get; }
public IpcMessage Response { get; } public IpcMessage Response { get; }
@ -21,6 +23,7 @@ namespace Ryujinx.HLE.HOS
Switch device, Switch device,
KProcess process, KProcess process,
MemoryManager memory, MemoryManager memory,
KThread thread,
KClientSession session, KClientSession session,
IpcMessage request, IpcMessage request,
IpcMessage response, IpcMessage response,
@ -30,6 +33,7 @@ namespace Ryujinx.HLE.HOS
Device = device; Device = device;
Process = process; Process = process;
Memory = memory; Memory = memory;
Thread = thread;
Session = session; Session = session;
Request = request; Request = request;
Response = response; Response = response;