OS X equivalent to OutputDebugString() ?
Asked Answered
A

4

14

I'm examining the feasibility of porting an existing Windows MFC control to OS X/Carbon. My test bed is a C++ Carbon application generated using the XCode 3 Wizard.

I'm looking for a quick way to dump some trace info to the debugger or the OS X equivalent of DbgView. On Win32 I'd use OutputDebugString() - what's the deal on OS X? Is there a way to view test written to std::cout from a Carbon app?

Thanks

Jerry

Alyssaalyssum answered 6/1, 2009 at 19:14 Comment(0)
I
20

There is no real equivalent. Xcode uses GDB under the hood, so you're basically dealing with that. You could, however, implement it yourself. The code sample below will produce output to standard out only when the debugger is present. You could further protect this by wrapping it in preprocessor directives as a macro and compile it out (or into an inline nil function) if NDEBUG is present at compile time. Any output produced by an application will be directed to the debugging console in Xcode.

extern "C" {

bool IsDebuggerPresent() {
    int mib[4];
    struct kinfo_proc info;
    size_t size;

    info.kp_proc.p_flag = 0;
    mib[0] = CTL_KERN;
    mib[1] = KERN_PROC;
    mib[2] = KERN_PROC_PID;
    mib[3] = getpid();

    size = sizeof(info);
    sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0);

    return ((info.kp_proc.p_flag & P_TRACED) != 0);
}

void OutputDebugString(const char *restrict fmt, ...) {
    if( !IsDebuggerPresent() )
        return;

    va_list args;
    va_start(args, fmt);
    vprintf(fmt, args);
    va_end(args);
}

}
Infidel answered 6/1, 2009 at 19:49 Comment(4)
Jason - I forgot to say thanks for this. Thank you, it is exactly what I needed. All I had to do was find the right .h to #include :)Alyssaalyssum
Also important to note the warning at the end : developer.apple.com/library/mac/#qa/qa1361/_index.htmlHolystone
It's a little better to write to stderr rather than stdout, so that it won't be buffered.Winepress
Could it be that writing to stderr or stdout does not work any more in OSX 10.10 when the app is launched via the Finder? I can't see any such output from my app in Console.app under "All Messages".Anti
I
14

First off, Carbon isn't and won't be available in 64-bit. If Apple ever drops 32-bit Mac OS X (which it's safe to assume will happen sooner or later), your app will not run. Use Cocoa.

That said, there are several ways to do logging:

  1. NSLog

This is a Cocoa function, but you can use it in Carbon apps, too. Link against the Foundation framework, but don't include the header. Declare it yourself:

    extern "C" int NSLog(CFStringRef format, ...);

You'll pass a CFSTR literal as the format:

    NSLog(CFSTR("Count: %u"), count);

The advantage of NSLog is that you can print CF property-list objects (strings, data objects, dates, numbers, arrays, and dictionaries) using the %@ formatter. For example:

    CFArrayRef array = /*...*/;
    NSLog(CFSTR("Array: %@"), array);
  1. printf/fprintf

The old C standard library standbys. #include <stdio.h> to get them. It doesn't matter much in a GUI app, but you should use stderr for cleanliness: fprintf(stderr, "Count: %u\n", count);

  1. syslog

About as old as f?printf, I'd guess, but more powerful. This is an actual logging system, not just writing to a file. You can specify things like priority, allowing you to suppress your debug log messages on beta testers' systems while still being able to read them on your own system. (Final releases should not contain logging code at all.)

  1. asl_log

Part of Apple System Logger, Apple's more general replacement for syslog. I have a series of posts about ASL on my blog.

Isborne answered 7/1, 2009 at 4:36 Comment(1)
+1 for fprintf(stderr, "foo bar"); works even in a QuickTime plugin. e.g. #7104814Rowley
A
5

You might want to look into syslog since it is the de facto diagnostic method on UNIX-based systems. Something like:

#include <syslog.h>

/* Do this early on in your program like at the beginning of main() */
openlog("MYPROGRAM", 0, LOG_USER);

/* Use this to log something */
syslog(LOG_DEBUG, "%s %s", "Hello", "World");

/* Do this somewhere before you exit if you being are pedantic */
closelog();

Google syslog for more information. You will also have to twiddle some bits in syslog.conf to direct the output to a log or console. Then you can view the output in a terminal window or using the Console application.

Alphaalphabet answered 6/1, 2009 at 20:22 Comment(0)
T
1

In Xcode you can see the output of std::cout/std::cerr in the "console" window (Run->Console).

There is also Console.app (in /Applications/Utilities) which logs all output written to std::cerr from GUI applications.

Tibbitts answered 6/1, 2009 at 20:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.