One our customer has trouble with our application written in .NET. It consumes entire CPU after the start of the process without any windows to show. It looks like an infinite loop.
The problem is, that this customer has Windows 7 Home Edition and that is why I cannot connect with remote managed debugger to the application.
I can create special version with some debugging mode. I consider I could run a thread in the begging of the process and after about one minute call Debugger.Break and somehow log the threads and the stackframes. I am not sure if it is possible to log stackframes on all threads.
Do you have some experience with such kind of debugging without debugger attached?
UPDATE:
After two days of strugling I have finally found the problem. It was bad ATI Graphic Card driver, which caused the infinite loop. Because some compontents use OpenGL. The problem was easilly uncovered by iterating threads of the current process, suspending them a writting the stacktrace. The code I finally use to uncover the error is following:
using System;
using System.Diagnostics;
using System.Text;
using System.Threading;
public class DebuggerContext
{
public int TimeIntervalMs { get; set; }
public Thread InfiniteLoopThread { get; set; }
}
public static class InfiniteLogger
{
public static void LogInfniteLoopAfterTimeInterval(int timeIntervalMs)
{
Thread watchdog = new Thread(Watchdog);
DebuggerContext context = new DebuggerContext()
{
InfiniteLoopThread = Thread.CurrentThread,
TimeIntervalMs = timeIntervalMs,
};
watchdog.Start(context);
}
static void Watchdog(object threadContext)
{
DebuggerContext context = (DebuggerContext)threadContext;
Thread.Sleep(context.TimeIntervalMs);
LogThread(context.InfiniteLoopThread);
var threads = Process.GetCurrentProcess().Threads;
foreach (var thread in threads)
{
if (thread == Thread.CurrentThread)
continue;
LogThread(context.InfiniteLoopThread);
}
}
private static void LogThread(Thread thread)
{
thread.Suspend();
StackTrace stackTrace = new StackTrace(thread, true);
string log = "The infinite loop is in: " + StackTraceToString(stackTrace);
Trace.WriteLine(log);
thread.Resume();
}
/// <summary>
/// http://stackoverflow.com/questions/51768/print-stack-trace-information-from-c-sharp
/// </summary>
/// <returns></returns>
static string StackTraceToString(StackTrace stackTrace)
{
StringBuilder sb = new StringBuilder(256);
var frames = stackTrace.GetFrames();
for (int i = 0; i < frames.Length; i++) /* Ignore current StackTraceToString method...*/
{
var currFrame = frames[i];
var method = currFrame.GetMethod();
var line = currFrame.GetFileLineNumber();
var file = currFrame.GetFileName();
var column = currFrame.GetFileColumnNumber();
sb.AppendLine(string.Format("{0}:[{1},{2}], {3}.{4}",
file,
line,
column,
method.ReflectedType != null ? method.ReflectedType.Name : string.Empty,
method.Name
));
}
return sb.ToString();
}
}
[STAThread]
static void Main(string[] args)
{
InfiniteLogger.LogInfniteLoopAfterTimeInterval(30 * 1000); //log thread state after 30 seconds after start
....
}