Unable to set a symbolic breakpoint to some Classes - ios

I had to investigate when a certain cookie was being set but unfortunately, I couldn't figure it out just seeking in the codebase. So as usual, when the game gets tough, I go and set a symbolic breakpoint. This time, against all odds, I wasn't able to.
In particular, I have been trying to set a symbolic breakpoint to the NSHTTPCookieStorage method setCookie: and neither from the Breakpoint navigator nor from the debug console I couldn't manage to set it.
For example:
(lldb) br set -F '-[NSHTTPCookieStorage setCookie:]'
Breakpoint 6: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations.
I have also tried to set the Module (Foundation) but nothing changed. The same happened also for the NSURLSession method downloadTaskWithResumeData:completionHandler: Then I tried with some other Foundation's classes and it always worked, except for all of those who are part of this group inside the Apple Documentation as NSHTTPCookieStorage and NSURLSession.
I thought it could be related to some security concerns but I also remember I applied a symbolic breakpoint to some Keychain and SecKey's symbols.
Did anyone else experience the same? I haven't found any doc where something similar was mentioned.

I do get a resolved bp in my case with the same:
br set -F '-[NSHTTPCookieStorage setCookie:]'
command (side note b '-[NSHTTPCookieStorage setCookie:]' would work to).
It seems in your case lldb has not loaded CFNetwork for whatever reason.
Mine
image lookup -vn '-[NSHTTPCookieStorage setCookie:]'
yields
1 match found in /Users/myusername/Library/Developer/Xcode/iOS DeviceSupport/12.4.1 (16G102)/Symbols/System/Library/Frameworks/CFNetwork.framework/CFNetwork:
Address: CFNetwork[0x0000000181478fbc] (CFNetwork.__TEXT.__text + 51832)
Summary: CFNetwork`-[NSHTTPCookieStorage setCookie:]
Module: file = "/Users/myusername/Library/Developer/Xcode/iOS DeviceSupport/12.4.1 (16G102)/Symbols/System/Library/Frameworks/CFNetwork.framework/CFNetwork", arch = "arm64"
Symbol: id = {0x00000af7}, range = [0x00000001b6628fbc-0x00000001b6629020), name="-[NSHTTPCookieStorage setCookie:]"
If you're on real device try
image add '/Users/myusername/Library/Developer/Xcode/iOS DeviceSupport/12.4.1 (16G102)/Symbols/System/Library/Frameworks/CFNetwork.framework/CFNetwork'
(obviously path substitute for appropriate iOS version^)
If you're on simulator try
image add '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/CFNetwork.framework/CFNetwork'
If you don't get an error then try setting your symbolic breakpoint at that point.

Related

How to reinstall / reset lldb?

My LLDB seems like broken by a plugin. Its output seems a little bit weird like this:
Process 771 stopped
* thread #1, stop reason = signal SIGSTOP
frame #0: 0x0000000100ac1000 cy-5Xn7dn.dylib`_dyld_start
cy-5Xn7dn.dylib`_dyld_start:
I don't know what cy-5Xn7dn.dylib is and I want to reinstall/reset my LLDB to fix this problem. Is there any possible way to reinstall or reset it?
Update:
This is otool information:
$ otool -l /usr/bin/lldb|grep " name"
name /usr/lib/dyld (offset 12)
name /usr/lib/libxcselect.dylib (offset 24)
name /usr/lib/libSystem.B.dylib (offset 24)
It looks like something is loading an alternative to the normal dynamic loader into the program you are running? I don’t think this is something lldb is doing, however. It is just relaying to you the dynamic library information that it got from the dynamic loader.
I’d first find that oddly named library and see if that tells you anything. You can use the lldb ‘image list <library_name>’ command to get the full path to the library. Is that in a place that maybe explains what it is?
It is possible to specify an alternate dynamic loader with the LC_DYLINKER command in the main binary. You might check the program you are debugging to see if it is doing that.
The DYLD_INSERT_LIBRARIES environment variable can also be used to force a program to load some other dylib. You should also make sure that isn’t being set. You can use ‘expr (char *) printenv(“DYLD_INSERT_LIBRARIES”)’ in lldb to check What it is in the app directly.

Cannot resolve enum values by name in Xcode debugger

With an enum typedef'd in a global header file used throughout my project, I am unable to refer to the individual enum values by name while using lldb in Xcode.
For example, if I am stopped at a breakpoint anywhere the enum type is available, and I try to evaluate something at the lldb prompt in Xcode (e.g. (lldb) p (int)EnumConstant), lldb complains:
error: use of undeclared identifier 'EnumConstant'
Furthermore, if I try to set a conditional breakpoint using an enum constant in the condition (e.g. right-click breakpoint in Xcode > Edit Breakpoint... > Condition: EnumConstant == someLocalVar), then Xcode complains every time it tries to evaluate that condition at that breakpoint:
Stopped due to an error evaluating condition of breakpoint 1.1: "EnumConstant == someLocalVar"
Couldn't parse conditional expression:
error: use of undeclared identifier 'EnumConstant'
Xcode's code completion popover even resolves a suggestion for the enum constant when I begin typing the name in the "Edit Breakpoint..." window, so Xcode itself doesn't have a problem resolving it.
Is there an option I can set in lldb or Xcode so that lldb maintains the enum identifiers after compilation? I'm assuming the enum constants get translated to their ordinal value during compilation, causing the executable to discard the identifiers, but thats just my naive speculation.
When I use the equivalent code in a simple GNU C program in Linux or Cygwin (minus the class definitions obviously), but using gcc/gdb instead of Xcode/lldb, I don't have these problems. It is able to resolve the enum values no problem.
I've created a tiny Xcode iPhone project to demonstrate what I mean. Using any of the enum_t constants below within the ViewController.m context (the for-loop is a good place to demo) will produce the same results.
ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
typedef enum
{
eZero, eOne, eTwo, eCOUNT
}
enum_t;
extern NSString const * const ENUM_STR[];
#end
ViewController.m:
#import "ViewController.h"
#implementation ViewController
NSString const * const ENUM_STR[eCOUNT] = { #"eZero", #"eOne", #"eTwo" };
- (void)viewDidLoad
{
[super viewDidLoad];
for (enum_t value = eZero; value < eCOUNT; ++value)
{
NSLog(#"%-8# = %d", ENUM_STR[value], value);
}
}
#end
This is a bug (fairly longstanding) in how the name->Debug Information lookup-accelerator tables for enums are built. While enum types are listed, enum values are not. That was surely done to save output debug info size - debug information gets quite big pretty quickly, and so there's a constant tension between the cost of adding more info and the utility of that more info. So far this one hasn't risen to the level of inclusion.
Anyway, doing a search through "all debug information for anything with a name that matches 'eZero'" is prohibitively slow even for decent sized projects, and gets really bad for large ones. So lldb always uses these name->Debug Info tables for its first level access.
Because the accelerator tables do contain the enum type by name (and more important for you typedefs by name as well), the workaround is to do:
(lldb) expr enum_t::eZero
(int) $0 = 0
Of course, if you have truly anonymous enums, then you are pretty much out of luck till this info gets added to the accelerator tables.
BTW, the Xcode symbol completion in the Debugger Console window is done using the Xcode SourceKit indexer, not lldb. So the completions offered from Xcode are not a reflection of lldb's knowledge of the program.
BBTW, gdb doesn't use compiler-made accelerator tables (these were an Apple extension up till the new DWARF 5 standard) but manually builds an index by scanning the debug info. That allows them to index whatever seems best to the debugger. OTOH, it makes debugger startup quite a bit slower for big projects.

Use of unresolved identifier false warning Swift 3 xcode

So I edited my post to be more clear. I am new in xcode and Swift 3 and I am facing to a strange problem. My project contains several swift files. I put all my simple common methods to Utils.swift, for instance simple string functions, etc. For many days I had no problems but after a point xcode is all the time complaining with red exclamation marks in all the files where I use my method if I am calling my methods from Utils.swift file: "Use of unresolved identifier 'xxx'".
// debug is a bool variable declared before
Utils.swift:
func log(_ message: String) {
if debug {
print(message)
}
}
ViewController.swift:
log("Error happened")
This gives an error "Use of unresolved identifier 'Log' ". Obviously the function is there so I don't understand why I get this red warning with exclamation mark during coding however when I click on Build, it is successful, and it runs perfectly and the warning is gone. As soon as I start typing again in the code area, the red error comes back. If I build it once more it is successful again. It doesn't make any sense to me.
I thought it is maybe a cache problem, xcode live issues function doesn't recognise my Utils.swift or something like this... so I cleaned the build folder (cmd + shift + option + K), I cleaned the project (Product > Clean), restarted xcode, restarted Mac, removed Utils.swift, re-added Utils.swift to the project but can not get rid of these false warnings during coding but if build the project it is OK. I don't have this problem in my other projects. Any idea?
Okay I found the answer myself. Clicking on the swift file (now Utils.swift) I had to select "Location Relative to Group" in file inspector and set the appropriate target memberships as well.
It is weird that despite the previous 'wrong' settings the build completes with success however it gives an error in the code area.

EXC_BAD_ACCESS code=1 because of #{}

I got a EXC_BAD_ACCESS code=1 because of a line like this:
NSDictionary* params = #{};
I didnt create the project, but i notice that have link to a c++ library, and have build setting that is not default (the setting generated by XCode). If i change this line by
NSDictionary* params = [NSDictionary new];
The issue is gone. Can it be something to do with the compiler's setting in project's build setting?
As a comment said this error is likely to be deep in your code. If the culprit is a zombie, the easiest way to find it is to run it (preferably in the latest Xcode, currently Xcode 8, as it has been improved) in profiler and choose "Zombies". When it fails, you can see the history of everything that has happened to the object.
Also, set an exception breakpoint. You may get a break when the error happens instead of in main, where the exception gets passed up.

string value always shows nil in objective C

I have upgraded to Xcode 5.0. And when I run an app in debug mode and try to print an NSString value in console, it gives me the below error. Any ideas?
error: warning: couldn't get cmd pointer (substituting NULL): Couldn't load '_cmd' because its value couldn't be evaluated
Couldn't materialize struct: the variable 'stringValue' has no location, it may have been optimized out
Errored out in Execute, couldn't PrepareToExecuteJITExpression
Here is the code:
NSString *stringValue = [[self.responseArray objectAtIndex:i] valueForKey:#"merchant_name"];
The reason is stated in the error message: it may have been optimized out.. this means that you are compiling and running your code in an optimized manner.
you gotta change your compiler optimization level from Fastest,Smallest to none:
go to your target build settings
search for optimization level
change it to none (whatever mode you are in ie debugging, distribution or release)
profit
do the same for your project settings
Make sure you are in debug mode. Go Edit Scheme > Build Configuration > Debug
You might be trying to debug in the "release Scheme". Go to "Product/Scheme/Edit Scheme" and pick the "run" in the left panel. Then change the build configuration to "debug".
One alternate answer: instead of fixing "it may have been optimized out" by removing the optimization, you can stop it from being optimized by using the variable.
So, in your question, if you do something with stringValue:
NSString *stringValue = [[self.responseArray objectAtIndex:i] valueForKey:#"merchant_name"];
NSLog(#"%#", stringValue);
stringValue will no longer be optimized out because you're using it.
If you want to see all instances of optimized-out variables in your project, Use Product -> Analyze to analyze your project. Any "Dead store" warnings (in which a value is stored, and never read) will be optimized out at compile time if you have compiler optimization turned on.

Resources