Instrumenting to debug freezes on client's machine

Hello, all!

An instance of my program is freezing on a machine (running OS/X) that I don’t have direct access to. This is complexified by the fact that we have a very similar testing machine in-house, where the software works well.

This probably isn’t very useful, but it freezes when the user drags things around.

  1. I’m going to give the client an instrumented, debug version of our program. Any suggestions about what to instrument?
  2. Is there a way for a naive user to get a dump of what all the threads are doing on OS/X and send it to us?
  3. One day this will happen with our Windows build - knowledge about that would also be helpful.

Thanks in advance!

You might want to try different input devices, e.g. mouse vs trackpad vs graphics tablet? I’ve got all three of those on my mac, and they all generate events at different rates - perhaps one of them is swamping your app with messages?

Well, we have a machine quite similar to the user’s machine, with the same hardware, and we don’t see the issue there.

I’m going to give them a debug build, but what I’d love is a way to say, “When it freezes, do this thing, then send us this file”. Unfortunately, force-quit doesn’t seem to leave a trace of where they were in any console or crash log.

My personal theory is that this freeze is some sort of conflict with either an add-on or some setting on the user’s machine. I’m going to get more information out of them!

I should add that the stability of this program has been super-fantastic. I developed this on the Mac, and I personally didn’t test Windows so heavily (though our testers of course did) and yet the Windows version has been rock-solid - we literally haven’t had a single trouble report on Windows since the release, and the only Windows-only issue was that “phantom blu-ray drive” issue, which was in the category of “entertaining bug” (since it didn’t prevent people from using the program, and had an obscure, fairly easy to find, and entertaining resolution).

We have only two issues on the Mac, this one, and another one that I strongly believe is due to our copy protection wrapper (i.e. nothing to do with Juce). This is interesting because Mac sales are about half those of Windows…

I had a similar problem recently on a client’s machine although semi-fortunately for me it was crashing and so generated an error report with a complete call stack.

What I was going to do was create a ‘logged’ version of the app that basically spat out all of my DBG macros to a log file on the desktop and then get them to send it to me. At least this lets you know where the program got up to. The class was really simple so here it is:


#ifdef LOG_TO_FILE
#define LOG(text) { DBG (text); juce::String tempDbgBuf; tempDbgBuf << text; juce::Logger::writeToLog (tempDbgBuf); }
#define LOG(text) DBG(text)

class ErrorLogger : public Logger


void logMessage (const String& message);

File logFile;
ScopedPointer logStream;


logFile = File::getSpecialLocation (File::userDesktopDirectory).getChildFile (“Application Name.log”);
logStream = logFile.createOutputStream();
if (logFile.existsAsFile())
logMessage (newLine + newLine + “==============================================================================”);
logMessage ("Application Name error log: " + Time::getCurrentTime().toString (true, true));


void ErrorLogger::logMessage (const String& message)
if (logStream != nullptr)
*logStream << message << newLine;

I then just did a find and replace for all the DBG to LOG and added a pre-processor definition LOG_TO_FILE when I wanted to build with this.

Just found out that if you open activity monitor, click on the process and then ‘Sample Process’ you get a complete callstack, very handy as long as you haven’t stripped your symbols. There’s also some other interesting stuff under ‘Inspect’. I think this is what you’re looking for.

Good ideas - particularly the Activity Monitor solution, I didn’t know about that and it will be just the ticket for me!