Symbolic breakpoint on Macro in XCode - ios

I'm using CocoaLumberjack (https://github.com/CocoaLumberjack/CocoaLumberjack) in my application.
It has a couple of different log macros that I use for example:
DDLogInfo
DDLogVerbose
DDLogWarn
DDLogError
These are defined as macros. I want to create a symbolic breakpoint that will break on all DDLogError. How do I do that?

In short, you don't. Macros are precompiler directives. By the time your program is compiled and running, macros are gone.
Symbolic breakpoints break on specific instance methods and function calls.
The best you might be able to do is to create a dummy method and edit the definition of your DDLogError macro to call that method. Then you could set a breakpoint (symbolic or actual) on that method.

lldb has a "source regular expression breakpoint" that might help out with this. It will search the text of your source files for some pattern and if the pattern matches set a breakpoint on that source line. You say:
(lldb) break set -p "DDLog"
It isn't as convenient for you maybe, because with no arguments it just looks in the current source file, and you can specify any number of files like:
(lldb) break set -p "DDLog" -f foo.c -f bar.c
but there's no way currently to say "all source files" so you might get tired typing all your files in. But if you only need to set these macro breakpoint in a few files, this might come in handy.

Related

Setting debugger breakpoints across all methods in an Xcode project

How do you trace all the methods invoked across different files in a particular user flow ?
Putting breakpoints at different points and observing the backtrace does not seem like the most efficient way.
Instead I would like to -
1) Put a breakpoint across all methods in the interested project.
2) Make all the breakpoints run a debugger command which prints out the file name and method name.
3) Edit the breakpoints such that the program continues to execute after a breakpoint is hit. (This option is available when you edit a particular
breakpoint.) So we don't stop at any breakpoint.
4) Disable all the breakpoints until I reach the flow I need to work on.
5) Enable all the breakpoints right before starting the flow.
With this approach, we don't have to manually put breakpoints at different places to understand the execution flow. Once the flow is complete, I can just look at the debugger console and figure out the execution flow.
Now, the question -
How can we do this using lldb commands?
Would appreciate any input/suggestions.
You can't do this with the Xcode breakpoint interface, but in the lldb console you can do:
(lldb) break set -r . -s AppName
Breakpoint 1: 478 locations.
(lldb) br com add
Enter your debugger command(s). Type 'DONE' to end.
> bt
> continue
> DONE
(lldb)
That sets a "symbol name match regular expression breakpoint" on all names ("." matches everything) in the binary/shared library called AppName. If you leave off the -s option, it will match all symbols everywhere. That will work but quite slowly...
The command prints a backtrace and continues.
This makes just ONE breakpoint, so you can do:
(lldb) break disable 1
Till you need it, and then enable it with:
(lldb) break enable 1
If you only want to catch some methods, you can adjust the regular expression, and if you find you aren't interested in some of the places you are hitting, you can individually disable locations within the breakpoint you've made this way.
(lldb) break list 1
Will show you all the locations, and:
(lldb) break disable 1.2-1.10 1.15
etc. will disable the locations.
This might get a little slow, because your app will be starting & stopping all the time. But it will do what you are asking.
You can put breakpoints on all methods in different files, and to trace how execution happens within that method click on Stepover.
Step over - shortcut - f6, it stops execution at next loc.
Also alternatively you can check value of particular variable or array by typing "po VariableName" in output window.
you can add related methods name through adding the symbol exception breakpoints.

lldb breakpoint on all methods in class objective c

How can I automate setting a breakpoint on all methods in an Objective C class using lldb?
This is useful for learning the behavior of a complicated legacy class. I am using Xcode (includes lldb) for iOS development, and it is cumbersome to manually go through the (large) file in Xcode and click the gutter next to each method to set breakpoints.
One option is to use regex breakpoints.
breakpoint set -r '\[ClassName .*\]$'
You can play around with the regexp to suit your needs.
The command will create a breakpoint that stops on all methods implemented by that class. However, there will be no breakpoints on methods inherited from superclasses.
To get methods on the superclass, you'll have to use a conditional breakpoint. For example, if the superclass is UIViewController, you could do something like:
br s -r '\[UIViewController .*\]$' -c '(BOOL)[(id)$arg1 isKindOfClass:[CustomVC class]]'
For x86 change (id)$arg1 to *(id*)($ebp+8).
Finally, if you really want to learn about the control flow through various classes, check out dtrace. It's probably more suited to this than a debugger.
br se -f FooViewController.m -p '^#property|^ *- *\('
"br se" is short for "breakpoint set", pass your own filename to the -f argument, and the -p argument is a crude regex for properties and methods in Objective C.
Caveats: This doesn't seem to work for .h files, so if you have properties declared in the header that you want to watch then you may need to set watchpoints on their backing instance variables.
This is the best solution I have found so far, please post alternative solutions if you think they will be helpful.

How to debug/log preprocessor macros in Xcode (iOS)?

The question is stated in title, the main purpose is to be able to efficiently debug some runtime-version-specific or scheme-specific code.
So for example, is it possible to log the value of DEBUG in xcode's console?
EDIT:
I should rephrase the question, I understand we can use NSLog("DEBUG = %d", DEBUG); to log a macro's value (thx #rmaddy), the question should be:
Is there better way? eg. not needing to add a command and recompile just to get the value of a single macro
The question seems a little confusing because of the mention of "runtime-version-specific". Preprocessor macros are compile-time settings rather than runtime settings.
If all you need is to find the iOS predefined macros for Xcode 6, type this into the terminal:
llvm-gcc -arch armv7 -dM -E – < /dev/null | sort
(Yes, there is a single dash by itself.)
Change the -arch option to “armv6″ or “armv7″ or “armv7s” as needed.
This can probably be extended to preprocess your project's code and show all the preprocessor macros. But that will be a compile-time operation rather than run-time.
To print the values of your custom macros at runtime would require specifically writing at least some code for each macro. Macros are tricky things. They may be #defined to one value or another or not #defined at all. They might also be #defined as numbers, or #defined as text, or object literals such as NSString, NSDictionary or NSNumber or any kind of object pointer.
The C standard "stringification operator" ('#') may be of interest if you really need to print things out at run-time.

Easiest way to debug objective-c classes in xcode?

I finished writing a class' .h and .m files in objective c in XCode and want to see if all the class functions are implemented correctly. I have not set up anything in the storyboard file yet but would like to test and debug the code. I'm looking to simply declare an object of the class type and to run some of the functions on it similar to using the command line with Python.
If there's no way to simply debug code using command line commands, what would be the easiest way to set up the storyboard?
You can use the XCTest to test your classes.
You can find all the information you need in the Apple documentation is actually pretty easy to use.
https://developer.apple.com/Library/ios/documentation/DeveloperTools/Conceptual/testing_with_xcode/testing_2_testing_basics/testing_2_testing_basics.html#//apple_ref/doc/uid/TP40014132-CH3-SW1
If you want you can check this tutorial as well.
http://rshankar.com/test-driven-development-in-ios-beginners-tutorial-part-1/
If you want you can set break points as well and check that your code is executing properly. Sometimes when I just want to proof-test small classes I do it just setting a couple of break points instead of the XCTest classes but it all depends on your study case. If you have a decent amount of classes I would suggest to use XCTest to check that the classes are actually doing what is expected setting your assertions and the other conditions that XCTest offers as a framework.
Another way you can do your testing if applicable is using NSLog to print in console lines or values of interest at each stage of your code execution.
You mentioned the command line. If you set breakpoints you can use po objName to print the value or print varName to check values of objects and primitive variables correspondingly. po stands for print object and print well... There's different options if you feel comfortable using the console just set NSLogs at certain point of your code or set the break points and print the values using po or print commands in the console.
Here you can check the string format specifiers for NSLog which are the same ones used for NSString
https://developer.apple.com/library/ios/documentation/cocoa/conceptual/Strings/Articles/formatSpecifiers.html

Path definition in makefile

I have a doubt about indicating a path in makefile and I'd like to have a clarification.
Suppose my structure is made this way:
/home/machinename/softwarefolder/mainfolder
--------------------------------------------> /subfolder1
--------------------------------------------> /subfolder2
This means that both subfolder1 and subfolder2 are at the same nesting level in /mainfolder.
Now I'm compiling something inside subfolder 2 (this means that I cd to that folder) that uses a configure file with a macro pointing to a path that, in my case, it's in subfolder1.
This configure file used by the program in subfolder2 to compile is generated automatically by the program itself after running ./configure
The automatically generated configure file has the macro defined this way
MACRO = ../subfolder1
Do the two dots (..) indicate, as in the cd command, "go back one step" (and, therefor, the configure file is pointing to the right folder)?
If the answer to the first question is "no", then why substituting the aforementioned macro with
MACRO = /home/machinename/softwarefolder/mainfolder/subfolder1
generates a "missing separator" error in compile-time?
Sorry for the probably trivial question and thanks for the help!
Make doesn't interpret the content of variables in any way, for the most part. The question of how the .. will be interpreted depends entirely on where the variable is used. If it's used in a place where a path like ../subfolder1 makes sense, then that's how it will be interpreted. If not, not.
Since you don't show how $(MACRO) is used, we can't help. But in general the answer to your question is "yes, it means go up to the parent directory".
As for your second question, there is no way I can envision that changing just that one line will result in a "missing separator" error. Maybe your editor "helpfully" made other changes to the file such as removing TABs and substituting spaces, or adding TABs? TAB characters are special in makefiles.
If you want help with the second question you must provide (a) the exact error you received (cut and paste is best), and (b) the exact text of the rule in the makefile at the line number specified in the error message.

Resources