2008-03-05 09:52:00 -05:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Microsoft Research Singularity
|
|
|
|
//
|
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
//
|
|
|
|
// Note:
|
|
|
|
//
|
|
|
|
|
|
|
|
using System;
|
|
|
|
using System.Collections;
|
|
|
|
using System.Diagnostics;
|
|
|
|
using System.Reflection;
|
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
using System.Threading;
|
|
|
|
|
|
|
|
using Microsoft.Singularity.V1.Services;
|
|
|
|
|
|
|
|
namespace Microsoft.Singularity
|
|
|
|
{
|
|
|
|
[NoCCtor]
|
|
|
|
[CLSCompliant(false)]
|
2008-11-17 18:29:00 -05:00
|
|
|
[AccessedByRuntime("referenced in halkd.cpp")]
|
2008-03-05 09:52:00 -05:00
|
|
|
public class DebugStub
|
|
|
|
{
|
|
|
|
/////////////////////////////////////////////////////// Print Methods.
|
|
|
|
//
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Print(byte value)
|
|
|
|
{
|
|
|
|
Print("{0:x2}", __arglist(value));
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Print(ushort value)
|
|
|
|
{
|
|
|
|
Print("{0:x4}", __arglist(value));
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Print(uint value)
|
|
|
|
{
|
|
|
|
Print("{0:x8}", __arglist(value));
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Print(ulong value)
|
|
|
|
{
|
|
|
|
Print("{0:x}", __arglist(value));
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Print(UIntPtr value)
|
|
|
|
{
|
|
|
|
Print("{0:x8}", __arglist(value));
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Print(sbyte value)
|
|
|
|
{
|
|
|
|
Print("{0}", __arglist(value));
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Print(short value)
|
|
|
|
{
|
|
|
|
Print("{0}", __arglist(value));
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Print(int value)
|
|
|
|
{
|
|
|
|
Print("{0}", __arglist(value));
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Print(long value)
|
|
|
|
{
|
|
|
|
Print("{0}", __arglist(value));
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Print(String value)
|
|
|
|
{
|
|
|
|
if (value != null) {
|
|
|
|
Print(value, new ArgIterator());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Print(String format, __arglist)
|
|
|
|
{
|
|
|
|
Print(format, new ArgIterator(__arglist));
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static unsafe void Print(String format, ArgIterator args)
|
|
|
|
{
|
2008-11-17 18:29:00 -05:00
|
|
|
WriteLine(format, args);
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Write(String value)
|
|
|
|
{
|
|
|
|
if (value != null) {
|
2008-11-17 18:29:00 -05:00
|
|
|
WriteLine(value, new ArgIterator());
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Write(String format, __arglist)
|
|
|
|
{
|
|
|
|
Write(format, new ArgIterator(__arglist));
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static unsafe void Write(String format, ArgIterator args)
|
|
|
|
{
|
2008-11-17 18:29:00 -05:00
|
|
|
WriteLine(format, args);
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void WriteLine()
|
|
|
|
{
|
|
|
|
WriteLine("", new ArgIterator());
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void WriteLine(String value)
|
|
|
|
{
|
|
|
|
if (value != null) {
|
|
|
|
WriteLine(value, new ArgIterator());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void WriteLine(String format, __arglist)
|
|
|
|
{
|
|
|
|
WriteLine(format, new ArgIterator(__arglist));
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static unsafe void WriteLine(String format, ArgIterator args)
|
|
|
|
{
|
|
|
|
char *buffer;
|
|
|
|
int length;
|
|
|
|
int used = 0;
|
|
|
|
|
|
|
|
DebugService.PrintBegin(out buffer, out length);
|
|
|
|
try {
|
|
|
|
if (buffer != null) {
|
2008-11-17 18:29:00 -05:00
|
|
|
AddLineHeader(buffer, ref used, length);
|
|
|
|
int format_used = String.LimitedFormatTo(format, args, buffer+used, length-used);
|
|
|
|
used += format_used;
|
|
|
|
|
|
|
|
// If the line had \r or \n at the start, replace with spaces.
|
|
|
|
for (int i = 0; i < used; i++) {
|
|
|
|
char c = buffer[i];
|
|
|
|
if (c == '\r' || c == '\n') {
|
|
|
|
buffer[i] = ' ';
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove whitespace (including \r\n) from the end.
|
|
|
|
while (used > 0) {
|
|
|
|
char c = buffer[used - 1];
|
|
|
|
if (c == ' ' || c == '\r' || c == '\n' || c == '\t') {
|
|
|
|
used--;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add our own \r\n
|
2008-03-05 09:52:00 -05:00
|
|
|
if (used < length) {
|
|
|
|
buffer[used++] = '\n';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
finally {
|
|
|
|
DebugService.PrintComplete(buffer, used);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
/// <summary>
|
|
|
|
/// This method adds prefix to each line sent to the debugger, containing the app name,
|
|
|
|
/// process id, thread id, and thread name. The thread name can be changed by setting
|
|
|
|
/// the DebugName property of a thread.
|
|
|
|
/// </summary>
|
|
|
|
[NoHeapAllocation]
|
|
|
|
private static unsafe void AddLineHeader(char* buffer, ref int length, int maxLength)
|
|
|
|
{
|
|
|
|
uint processId = ProcessService.GetCurrentProcessId();
|
|
|
|
uint threadId = unchecked((uint)Thread.GetCurrentThreadIndex());
|
|
|
|
|
|
|
|
string appName;
|
|
|
|
string threadName;
|
|
|
|
#if DEBUG
|
|
|
|
appName = AppRuntime.AppName;
|
|
|
|
if (appName == null)
|
|
|
|
appName = "?";
|
|
|
|
|
|
|
|
Thread currentThread = Thread.CurrentThread;
|
|
|
|
if (currentThread != null) {
|
|
|
|
threadName = currentThread.DebugName;
|
|
|
|
if (threadName == null) {
|
|
|
|
threadName = "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
threadName = "";
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
appName = "?";
|
|
|
|
threadName = "";
|
|
|
|
#endif
|
|
|
|
|
|
|
|
InsertFormat(buffer, ref length, maxLength, "[{0,10} p{1,2} t{2,2} {3,6}] ", __arglist(appName, processId, threadId, threadName));
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
private static unsafe void InsertFormat(char* buffer, ref int length, int maxLength, String format, __arglist)
|
|
|
|
{
|
|
|
|
int count = String.LimitedFormatTo(format, new ArgIterator(__arglist), &buffer[length], maxLength - length);
|
|
|
|
length += count;
|
|
|
|
}
|
|
|
|
|
2008-03-05 09:52:00 -05:00
|
|
|
////////////////////////////////////////////////////// Assert Methods.
|
|
|
|
//
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void NotImplemented()
|
|
|
|
{
|
|
|
|
failAssert("Not implemented.");
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void NotImplemented(String msg)
|
|
|
|
{
|
|
|
|
failAssert(/*"Not implemented: "+*/msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
[Conditional("DEBUG")]
|
|
|
|
[NoInline]
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void NotReached()
|
|
|
|
{
|
|
|
|
failAssert("Unreachable code reached.");
|
|
|
|
}
|
|
|
|
|
|
|
|
[Conditional("DEBUG")]
|
|
|
|
[NoInline]
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void NotReached(String msg)
|
|
|
|
{
|
|
|
|
failAssert(/*"Unreachable code reached: "+*/msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
[Conditional("DEBUG")]
|
|
|
|
[NoInline]
|
|
|
|
[ManualRefCounts]
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Assert(bool expr)
|
|
|
|
{
|
|
|
|
if (!expr) {
|
|
|
|
failAssert(null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[Conditional("DEBUG")]
|
|
|
|
[NoInline]
|
|
|
|
[ManualRefCounts]
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Deny(bool expr)
|
|
|
|
{
|
|
|
|
if (expr) {
|
|
|
|
failAssert(null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[Conditional("DEBUG")]
|
|
|
|
[NoInline]
|
|
|
|
[ManualRefCounts]
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Assert(bool expr, String s)
|
|
|
|
{
|
|
|
|
if (!expr) {
|
|
|
|
failAssert(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[Conditional("DEBUG")]
|
|
|
|
[NoInline]
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Deny(bool expr, String s)
|
|
|
|
{
|
|
|
|
if (expr) {
|
|
|
|
failAssert(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
[ManualRefCounts]
|
|
|
|
[NoHeapAllocation]
|
|
|
|
private static void failAssert(String s)
|
|
|
|
{
|
|
|
|
if (s != null) {
|
|
|
|
Print("Assertion failed: {0}", __arglist(s));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Print("Assertion failed.");
|
|
|
|
}
|
|
|
|
Break();
|
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static ulong ReadPerfCounter(uint which)
|
|
|
|
{
|
|
|
|
return DebugService.ReadPerfCounter(which);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static bool WritePerfCounter(uint which, ulong value)
|
|
|
|
{
|
|
|
|
return DebugService.WritePerfCounter(which, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static bool AddToPerfCounter(uint which, ulong value)
|
|
|
|
{
|
|
|
|
return DebugService.AddToPerfCounter(which, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////// State Methods.
|
|
|
|
//
|
|
|
|
#if true
|
|
|
|
[AccessedByRuntime("output to header : defined in halkd.cpp")]
|
|
|
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
|
|
|
[StackBound(638)]
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static extern void Break();
|
|
|
|
#else
|
|
|
|
[NoHeapAllocation]
|
|
|
|
public static void Break()
|
|
|
|
{
|
|
|
|
DebugService.Break();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|