How do I output custom warnings to the console in Xcode? I want to do this to remind myself that I'm in a particular build mode.
I tried #warning "Hello World" but I don't see it in the console.
Any suggestions?
Edit:
I don't want to use NSLog because I am already using it to log a bunch of stuff so when I use NSLog for warnings, it is difficult to see all the warnings.
#warning directive
The #warning directive is to see the message on the compiler. This is very handy to know that something must be changed before deploying or simply to remember to change a piece of code that can be improved (but you don't have the time to do so now). (go to View -> Navigators -> Show Issue Navigator on your project and you will the see the list of warnings). These messages will not appear on the console.
The Apple System Log facility
What you want is to show a warning to the console while the app is running and here is where The Apple System Log facility comes to the rescue.
You have 8 logging levels:
0 Emergency.
1 Alert
2 Critical
3 Error
4 Warning
5 Notice
6 Info
7 Debug
Code sample:
#include <asl.h>
...
asl_log(NULL, NULL, ASL_LEVEL_INFO, "Hello World!");
Since I was in the same situation than you once, and to make things simple, I use this wrapper https://github.com/MikeWeller/MWLogging in all my projects so my debug errors won't show when I send my App to the App Store but other critical error will.
Update: Now with Swift I use this debug log framework https://github.com/DaveWoodCom/XCGLogger
You can use NSLog
In state of your warning use something like:
NSLog(#"Hello World");
Or you can use the standard C printf function:
printf("Hello World");
If you want to be printed on stderr you can use fprintf redirected to stderr.
Related
I have:
AFHTTPRequestOperation* operation;
...
if ([operation.request.URL.path isEqualToString:somePath])
{
...
}
When I print it out I get:
(lldb) po operation.request.URL.path
/users/12345678/data/something
But when I hover over the variable path, the Xcode popover shows:
users/12345678/data/something
Why?
ps: Shown URLs are purely fictional :-) But it really does happen here and now.
To err on the side of caution, yes, do what Jason said and file a bug, and we will look at it.
On the other hand, be aware that in general, "po" works by running an API on your object provided by the framework vendors. Hovering in Xcode works by invoking the LLDB data formatters provided by the LLDB team.
There is no promise that the two will agree in the way they choose to represent objects (cfr. po #[#1,#2,#3] with p #[#1,#2,#3] to see this very clearly)
This sounds like a bug. If you can make a small self-contained repro example project, I'd encourage you to file a bug report at http://bugreport.apple.com/
I have a message from it seems Core Foundation printing into the debug console in XCode (OS X app), "CGContextGetCompositeOperation: invalid context 0x0. This is a serious error....".
I don't know where in my app this line is being generated. (big app)
I tried breaking on NSLog(), CFLog() syslog(), printf(), fprintf, and none of those breakpoints stop on that output. All of those breakpoints work if I test them, etc.
Is there a symbol I can break on that will stop every time a message is printed to the console?
Or is there some function that Apple uses that I can break on?
Is it possible to access the properties of objects in xCode console?
If I try the following I get an error that he property doesn't exist.
po someObject.someprop
If I don't breakpoint the code and run the app it works fine so I know someObject.someprop exists. I don't think I have the grasp on xCode console yet? What I loved about Flex/Flash development is that I could set a break point and in the console window or variables view I could traverse every structure down to the ends of the earth.
I could see SomeDicionary[key].someArray[1].someObject.prop and it would show me the value. Is this not possible in xCode console or is there a trick to get to it?
You'll actually have to use the bracket syntax notation:
po [someObject someprop]
The debugger is sometimes very finnicky about syntax. This is filled with all sorts of helpful tips for debugging in XCode.
Just a side note, variables/properties declared in the implementation file (*.m) instead of the header file (*.h) can sometimes be invisible to the debugger variable list display depending on if the breakpoint is in that class's code, because of scope. Not necessarily required here, but useful to know seeing as how it is kind of relevant.
I'd like to move from NSLogging all over the place to using breakpoints for logging where the performance hit doesn't preclude it.
I know I can just po an object with a Debugger Command action, and I know I can just log any string by choosign the Log Message action.
And I think I should be able to combine both by choosing Log Message and entering something like SomeText giving context for object description: #(const char *)[[anObject description] UTF8String]#. Unfortunately, this doesn't seem to work, and always gives me what I assume to be the pointer to the description string.
What am I doing wrong?
It's kinda tricky but I think that this will work. Set the breakpoint Action as a debugger command. Then use this text as the action:
po (NSString *) [#"Some text describing: " stringByAppendingString:(NSString *)[anObject description]]
You must always be very careful to cast return types when working in the debugger. Both with GDB and LLDB.
I like your idea of using breakpoints to avoid the performance hit, but this also means that your logs will only be printed when connected to a debugger. While NSLogs will buffer their output to the system log, viewable from the Organizer (Devices) in Xcode.
(Edit: I missed the question's point and it's not an answer)
I think it's best to use DebugLog. It's a macro, and you can disable it easily (it's on when you def-ine DEBUG in your debug builds and is off when you don't define it). So, there's no performance degradation (quite the contrary).
Simply replace
NSLog(#"Hello, World!");
with
DebugLog(#"Hello, World!");
And instead of
19/4/12 8:55:52.949 PM Dictionary: Hello, World!
You'll get:
BetterDictionary.m:737 Hello, World!
(it shows which file and even which line has logged it)
Which is infinitely more interesting. undefine DEBUG for your production build and DebugLog won't be called at all.
And don't forget to #import 'DebugLog.h'.
I have an NPAPI plug in running on OS X 10.6.8 that I'd like to debug. When I load it using FireFox 3.6.19, I can set the active executable to FF, start FF, attach using XCode, and the breakpoint will fire at the expected time.
When using Safari 5.1, I see that the plug in runs out of process, so I created and activated a customer executable for /System/Library/PrivateFrameworks/WebKit2.framework/PluginProcess.app. I then start Safari, navigate to the page hosting the plug in, attach to the plug in process, and then use the UI such the breakpoint should fire, but it doesn't. I can tell by the UI that the plug in definately loaded. If the pause the process, I see:
(gdb) i b
Num Type Disp Enb Address What
1 breakpoint keep y <PENDING> "ADP_NPAPI_Interface.m":34
2 breakpoint keep y <PENDING> "ADP_NPAPI_Interface.m":34
3 breakpoint keep y <PENDING> "ADP_NPAPI_Interface.m":34
4 breakpoint keep y <PENDING> "plugin.cpp":244
5 breakpoint keep y <PENDING> "plugin.cpp":358
6 breakpoint keep y <PENDING> objc_exception_throw
(gdb) show directories
Source directories searched: $cdir:$cwd
(gdb) info sources
No symbol table is loaded. Use the "file" command.
(gdb) file sources
sources: No such file or directory
(gdb) info file
No registers.
No registers.
(gdb) show paths
Executable and object file path: /Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin
DEBUG_INFORMATION_FORMAT = dwarf-with-dsym. My understanding is that the symbols will be in the plug in, so, I believe that gdb can't find my source files.
Thanks in advance for your help,
Dave
One method that I have used occasionally with FireBreath plugins is this:
#if WAIT_FOR_DEBUGGER
static bool beingDebugged() {
int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; size_t mib_size = 4;
struct kinfo_proc kp; size_t kp_size = sizeof(kp);
int result = sysctl(mib, mib_size, &kp, &kp_size, NULL, 0);
return (0 == result) ? (P_TRACED & kp.kp_proc.p_flag) : false;
}
#endif
Then in one of the entrypoints (such as NP_Initialize) you do:
#if WAIT_FOR_DEBUGGER
#warning "WILL BLOCK ON P_TRACED"
while (!beingDebugged())
sleep(1);
#endif
A friend of mine came up with this, and it seems to work pretty well. However, you should know that in Safari 5.1 the browser will kill the plugin (send a SIG_KILL) after a (fairly brief) time of not getting a response from it. Because of this, it's nearly impossible to debug with Safari 5.1; I highly recommend you debug in either Firefox or Chrome because of this.
This will cause the plugin to wait for your debugger to attach. Note that in Safari 5.1 the name of the plugin process has changed; I forget what it is now exactly, but it's definitely out of process and it's not Safari =]
One of these days I'll get around to adding this to the default FireBreath np_mainmain.cpp file....
Xcode has an option to Run ->Attach to process. Use this to attach to plugin process and not the browser. From here you can start debugging plugin running in 64 bit browser
The "with-dsym" part of dwarf-with-dsym means that the symbols are in a separate symbol file, not in the binary.
Your options are:
- sWitch to plain dwarf
- copy the .dsym bundle from your build directory to next to the installed plugin
- manually load the dsym in gdb (at least, I believe this is possible; I haven't actually done it though)