I am trying to set a watchpoint while debugging my app on the device. I am unable to set it on either gdb or lldb.
On lldb, I don't see the watchpoint set option in the debugger even though this page mentioned that it exists. When I try to run watchpoint set, lldb tells me that the command is not valid.
On gdb, I do get to set the watchpoint (using watch var), but when I try to continue execution I get this:
Can't set hardware watchpoints without the 'Z2' (write-watchpoint) packet.
I see no further output in the gdb window nor do I think I can interact with it. The app also remains hung at this point.
I am using Xcode 4.3.2 (4E2002) on OS X Lion. I tried setting the watchpoint on devices with iOS 5.1 and iOS 5.0.1 but encounter the same problem on both.
Before Xcode 4.5, watchpoints were not supported for iOS development with either lldb or gdb.
With Xcode 4.5, they are supported for iOS and Mac OS X debugging with lldb.
In Xcode, in the locals window, you can right-click/control-click on a variable and there will be an option to set a watchpoint on it. From the debugger console, to add a watchpoint on a variable called foo, you can do
(lldb) watchpoint set variable foo
the shortest unambiguous command is always valid in lldb so this would do the same thing,
(lldb) w s v foo
The current x86 and arm cpus only support 4 watchpoints being set simultaneously.
I read this somewhere in the Apple Dev Forums :
"The set command exists in the trunk version but not in the Xcode version yet."
I am also stuck with this problem where I want to keep a watch on a variable and see where its value changes...
Related
Nothing prints from NSLog on Xcode 8.0 beta (8S128d). printf is unchanged
Here's my code:
NSLog(#"hello from NSLog");
printf("hello from printf");
Here's the output on iOS 9 Simulator:
2016-06-17 09:49:10.887 calmapp-dev[28517:567025] hello from NSLog
hello from printf
Here's the output on iOS 10 Simulator:
hello from printf
It could be that you added the property "OS_ACTIVITY_MODE": "disable" in the Scheme environment variables (to hide OS output from the simulator) and forgot about it, and now are running on a real device.
In Xcode 8:
Product -> Scheme -> Edit Scheme -> Run -> Arguments -> Environment Variables
Only add OS_ACTIVITY_MODE and check it(Don't add a value)
Summary:
This is a bug of Xcode 8 + iOS10, we can solve it in this way:
When using the simulator, add the Name "OS_ACTIVITY_MODE" and the Value "disable" and check it.
When on a real device, only add "OS_ACTIVITY_MODE" and check it(Don't add the Value).
You will see the NSLog in the Xcode8 Console.
If you check the Xcode 8 beta release notes, you'll find that it says:
When debugging an app running on Simulator, logs may not be visible in the console.
Workaround: Use command + / in Simulator.app to open the system log in the Console app to view NSLogs. (26457535)
the NSlog or print actually is executed but is hidden among lots of other console debug outputs to solve this issue
Open Xcode8:
Product -> Scheme -> Edit Scheme -> Run -> Arguments -> Environment Variables
add "OS_ACTIVITY_MODE" and set the Value to "disable" and check it.
click close
xcode9
add "OS_ACTIVITY_MODE" and set the Value to "default" and check it.
Also, make sure the Console is actually visible in Xcode (i.e., make sure the right-hand side icon is highlighted in blue, as per the image below). After I upgraded Xcode, it hide the Console and showed me just the Variables view. This made it look like NSLog() was not working properly, whereas it was indeed working correct, I just couldn't see the output.
I can't see NSLog output in real iOS 10 device neither. If you're using real devices, you can open Devices window from Xcode (Shift + Command + 2) and see device logs there, but it's hard to look at your app's logs because the console shows logs from system and all apps.
(I'm using Xcode 7, so it's may not Xcode's problem but iOS 10 problem)
For anyone who comes upon this in the future. The reason NSLog doesn't print to syslog in iOS 10 and iOS 11 is due to Apple changing to Unified Logging.
You can see the WWDC talk about it here: https://developer.apple.com/videos/play/wwdc2016/721/
Documentation here: https://developer.apple.com/documentation/os/logging
From 10 on you should be using os_log instead of NSLog.
How to find the logs on disk: https://www.blackbagtech.com/blog/2017/09/22/accessing-unified-logs-image/
To summarize, the logs are located in /var/db/diagnostics which can be found for a VM at /Users/USERNAME/Library/Developer/CoreSimulator/Devices/SIMULATOR-GUID/data/var/db/
Copy all items inside diagnostics and uuidtext into a single folder (don't include the folders diagnostics or uuidtext just what is inside).
Rename that folder foldername.xarchive.
Open it in Console.app or use the OSX util log: log show <path to archive> --info --predicate <options>
Hmmm... it seems like the property "OS_ACTIVITY_MODE": "disable" PREVENTS NSlog from showing up in the Xcode 9 log.
Unchecking this value in my scheme restored my logs.
I'm using Xcode 8,so I also encountered the same problem . And I solved this problem by adding value = disable on the simulator, but on a real machine I don't add value.
NSLog messages no longer displayed when I upgraded to Xcode 9.1 + iOS 11.1. Initially the accepted answer gave me a way to work around this using the Console app and enabling the Simulator (see Lucas' answer).
In the Console app under Action I tried selecting Include Debug Messages and deselecting Include Info Messages (so the Console isn't swamped with system messages). NSLog messages appeared in the Console window in Xcode but not in the Console app.
I realised there had to be a more direct way to disable or enable (i.e. default) NSLogs thanks to Coeur's comment in response to this answer. In my opinion it is the best answer because setting OS_ACTIVITY_MODE to disable or default will make more sense for beginners.
Background
I have a fairly detailed (around 2000 lines of swift code) automation framework built with Xcode 7.3 and Swift for our iOS app.
Up till a recent point, I was able to use lldb to build my framework i.e
insert breakpoint and run code up till that point
use po XCUIApplication().debugDescription and expr bla bla to build the logic
repeat
Problem
Pretty much all of a sudden, I now encounter the following error whenever running anything inside lldb's console:
(lldb) po XCUIApplication()
error: <EXPR>:2:1: error: 'XCUIApplication' is only available on iOS 9.0 or newer
XCUIApplication()
^
<EXPR>:2:1: note: add 'if #available' version check
XCUIApplication()
^
<EXPR>:2:1: note: add #available attribute to enclosing instance method
XCUIApplication()
^
<EXPR>:2:1: note: add #available attribute to enclosing extension
XCUIApplication()
^
<EXPR>:10:9: warning: initialization of variable '$__lldb_error_result' was never used; consider replacing with assignment to '_' or removing it
var $__lldb_error_result = __lldb_tmp_error
~~~~^~~~~~~~~~~~~~~~~~~~
Notes
Googling and research has not gotten me anywhere significant.
The one relevant thread I found was in the fastlane project. Unlike that comment, mine is a UI Test target.
Also, the test target's "iOS Deployment Target" is set to iOS 9.2 (in case that helps).
To the extent I remember, I haven't changed anything significantly in recent times.
My device is (and has always been) iOS 9+.
What could be going wrong?
Update 20 May 2016
Some exploration based on the answer below: https://stackoverflow.com/a/37335950/682912
The issue happens only on real devices. Simulators do not face this problem.
On real device (iPhone 6S+, iOS 9.2.1), I did a full reset of Content and Settings. This did not fix the issue.
This is a bug in the debug agent installed on your device. These are bound to the iOS version, so it probably happened when you upgraded your device. Anyway, please file a bug with http://bugreporter.apple.com.
If I'm right about the problem, it should only happen when debugging to the device, not on the simulator. That might allow you a temporary workaround till the bug gets fixed.
Double check your .xcconfig with your test target or any other means that may set your IPHONEOS_DEPLOYMENT_TARGET to lower than 9.0.
Since UITest is only available on iOS9.0 or later, change IPHONEOS_DEPLOYMENT_TARGET to 9.0+ should fix the issue.
I'm having a very weird problem - as you can see in the picture below, the debug shows that the program entered to the if statement, but the value of color is shown as nil !!!
obviously that's can't be true, and I suspect that the Xcode is showing incorrect values on the inspector \ variable view (at the debug area).
I have no idea - maybe my Xcode had too much vodka?
any HELP please???
updates:
I tried to restart my mac - didn't help.
my Xcode version: 6.4
I've seen the "extracting data from value failed" message (when doing a po foo at the LLDB prompt), even on debug builds . This appears to be an LLDB bug.
A workaround that worked for me was to cast the value to the expected return type (e.g. if it's an NSNumber, po (NSNumber *)foo).
Check your scheme - Run tab on the left should have the Debug executable option checked.
If you are running on AdHoc \ Release mode, the debugger will not show the right values.
Change the "Build Configuration" to "Debug".
The Xamarin debugging documentation indicates:
Use Xamarin Studio's native debugging support for debugging C# and
other managed languages code and use LLDB when you need to debug C,
C++ or Objective C codethat you might be linking with your Xamarin.iOS
project.
However I cannot find any documentation on how to use LLDB to debug a Xamarin app. If I run my app in the iPhone Simulator and try to attach to it using LLDB I get the following error:
(lldb) attach --pid 37993
Process 37993 exited with status = -1 (0xffffffff) lost connection
error: attach failed: lost connection
Attaching using Xcode doesn't work either. I tried different variations of attach but none of them worked.
Can someone point me in the correct direction on how to debug Xamarin apps with LLDB? Moreover is this something I could do on the device and not just in the simulator? I didn't find any information on how to use LLDB to attach to a process on a device.
Update
It looks like the debugserver process is crashing whenever I use lldb to connect to my binary. Here is a link to the crash report for debugserver:
https://www.dropbox.com/s/9lizhl2quj9n0cc/debugserver_2015-07-07-131423_gauss.crash?dl=0
Update 2
When I run dtruss on the app it prints the system calls till it encounters
dtrace: error on enabled probe ID 2475 (ID 194: syscall::ptrace:return): invalid user access in action #5 at DIF offset 0
which happens when something calls ptrace(PT_DENY_ATTACH, 0, 0, 0); Why is PT_DENY_ATTACH called?
Update 3
I traced the ptrace system call to this function: mono_assembly_init_with_opt which happens very early in the life of the program. All that function does is call ptrace, so if I just return early from that function, I can debug with lldb.
Basically, I can do:
(lldb) process attach --name AppName --waitfor
# when the process starts
(lldb) b mono_assembly_init_with_opt
(lldb) c
# when the thread breaks
(lldb) thread return 0
(lldb) c
and now I can happily debug with lldb.
But, I shouldn't have to do this. Is there something wrong with my project config (I can debug simpler apps with lldb) or is Xamarin being evil?
Codesigned apps on Mac OS X can only be debugged if they have a particular attribute set in their app plist. You want something that looks like:
<key>SecTaskAccess</key>
<array>
<string>allowed</string>
<string>debug</string>
</array>
You can look at the man page for taskgated for a somewhat terse description of this process.
Usually for Xcode projects, this attribute gets consed up and inserted into your debug builds by Xcode, so you don't need to do anything to get this to happen.
I don't know how Xamarin works, but it is possible that it is not setting this attribute. On older OS X systems, root can debug anything, so you could try sudo -s and then debugging from there. But starting with Yosemite, the request not to be debugged is being more broadly honored...
Have you tried using the pid from the Activity Monitor? Just type your app name into the search box in Activity Monitor when running it in Debug.
If it still doesnt work can you try just creating a new project and attaching to that just to rule out any project config.
This happens to be a limitation imposed by Xamarin in the trial version. After upgrading to a paid license, this is no longer an issue. Even though Xamarin's website says:
When you begin a Xamarin Trial, you get access to the full Xamarin
Business feature set for 30 days.
It's clearly not the full feature set since they explicitly disable attaching lldb to the app if you are using a native library. I'm not sure the reason for doing so, maybe someone from Xamarin can comment on it.
Explanation
Thanks to Jim Ingham for pointing me in the right direction. The way Xamarin events debuggers from attaching to the app is by calling ptrace with PT_DENY_ATTACH. This system call enables the process to deny requests for debugging. (Detailed Explanation).
Moreover rather than calling the ptrace function directly, Xamarin tries to hide the call by using the syscall method (link).
Workaround
If you really need to debug your app and are still using the trial version, here is a workaround. The ptrace system call is made in the function mono_assembly_init_with_opt which happens very early in the life of the program. That function doesn't do anything else and can be skipped. Since the function is called right in the beginning of the process, we need to attach lldb before the function is called.
The steps are as follows:
Start lldb and wait for the app to start.
When the app starts, add a break point for mono_assembly_init_with_opt
Resume the app and when it stops at that function, return early without executing that function.
After this you can use lldb or attach Xcode to the app and debug your native code as usual.
Steps in lldb:
(lldb) process attach --name AppName --waitfor
(lldb) b mono_assembly_init_with_opt
(lldb) c
# when the thread breaks
(lldb) thread return 0
(lldb) c
This is ONLY regarding the new Xcode 4.1, specifically running on Lion. How do you enable NSZombie in Instruments ? It is no longer in Allocations in the (i) icon under Launch Configuration as in Xcode 4.0. Nor is there a Library entry called Zombies.
Of course the problem is I cannot fall back to Xcode 4.0 because it refuses to run under Lion, so I'm in a pickle ! Any other bleeding edge developers using Lion who, with more experience than myself, can help dig this out ? Thanks. -Ric
I got this very useful answer from Apple regarding my own question. It is verbatim -
ME: Is there an update as to how to find those tough deallocated objects, testing on the device, using Xcode 4.1.1 and/or Instruments ?
APPLE: First up, the hack shown above [in Apple's Forum] has been obsoleted by internal changes to the OS, namely, Zombie setup is now done by CF. You can force zombies enabled using the code shown below:
extern void _CFEnableZombies(void);
int main(int argc, char **argv)
{
_CFEnableZombies();
... rest of your main ...
}
IMPORTANT: The _CFEnableZombies function is private, so you don't even think about putting this code into a production app. However, it's not secret; you can see how it's implemented by looking in the Darwin open source for Lion.
http://www.opensource.apple.com/source/CF/CF-635/CFRuntime.c
If you do this, your app will stop (with a breakpoint exception) when you message a zombie, regardless of how you run it. So you can run it in Instruments with the Allocations instrument and get both zombie detection and allocation tracking.
Note that when a zombie is messaged the system prints something like this:
*** -[ ]: message sent to deallocated instance "
This doesn't appear in the Instruments console area; you'll have to use the Xcode Organizer (or iPCU) to view it.
Share and Enjoy
Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
ME: hope that is useful info for some of you in this situation.
It's a distinct instrument:
There is another way to run with NSZombie on the device, but this is done through XCode 4 not instruments.
To run with NSZombie on the device open your XCode Project and click on the top menu item "Product" then hold down alt and click "Run" this will open a separate window where you will see "Environment Variables" in the bottom of the window. Hit the "+" and enter "NSZombieEnabled" for the name and "YES" for the value.