iOS App Breakpoints on Running

How to hit a breakpoint in application while running UI test in iOS?

Select your test scheme and go to Edit Scheme...

Select 'Test' in the sidebar and in the 'Info' category check the 'Debug executable' option.

When you run the tests in that scheme, breakpoints in both the test target and the app under test will be hit.

Is it possible to use XCode's Instruments with breakpoints enabled?

I also ran into this issue today, and after a bit of searching I found this solution. Text below is a quote from the post:

Breakpoints Do Not Break. Instruments utilizes debug information from
your debug build, however, it does not stop at break points you set.
This is because while you are loading your application into
Instruments from the menu in XCode, Instruments simply uses the path
of the current executable as its start path and loads it externally
from XCode. The menu in XCode is really there as a convenience
mechanism. This is not a big deal as you can always run again in Debug
mode after your instruments session should you want your application
to break. It’s just something to make a note of.

NSLog Statements Do Not Show In The Debugger Console. If you want to
see your NSLog statements, you will need to load the system Console
application (/Applications/Utilities/Console).

Reference: http://www.cimgf.com/2008/04/02/cocoa-tutorial-fixing-memory-leaks-with-instruments/

When running the IntentsExtension, how can I also debug the main app?

The run scheme for the Intent Extension has some additional options for running. One of those options includes a checkbox that says Debug executable. If you check that box, then xcode will also respect any breakpoints set in the main app, as well as emit any logs from the main app. Make sure you have your app selected under "Executable" as well!

Sample Image

Xcode debugging breakpoints when app is launched from outside of Xcode

In the time it takes the debugger to notice and attach to your process execution of the process has proceeded past the breakpoints. To get deterministic behavior from the debugger in this setup you need to pause execution of your process prior to the first breakpoint and wait for the debugger to attach. A simple way to do this is by adding code to send the STOP signal:

raise(SIGSTOP);

Execution will stop at this point and the debugger will automatically continue when it attaches.

Debugging while app is not running

You can launch the app in Xcode but set the scheme to wait for an external launch trigger. In this mode Xcode will watch and wait for something else to open the app.

To do this, edit the scheme, select the info section and then select Wait for executable to be launched.

iOS app breakpoints on running

You have two breakpoints set on the print method. Breakpoints are shown in the left margin as blue flags. You can get rid of them by dragging them out of the margin, like this:

dragging breakpoints out to remove them

Xcode 9 - Framework breakpoints

TL;DR - I needed to change which directory my archive script reads from when debugging or when preparing a release. Now when debugging, I need to be sure to set my framework scheme's archive config to "Debug" if I want breakpoints to work properly at runtime. I only use "Release" when preparing a production-ready .framework.

I reached out to Apple developer support via bug report. I will paste the response below. When he mentions "lipo", he is referring to a call I make in a post-archive script that creates a universal framework from the simulator and physical device builds.

Xcode has to match up the binary that's running with the debug symbols that are still on your machine. Xcode should do that automatically, but it sounds like some stuff is moved around behind Xcode's back. To know whether the debug information matches you can look at the output of
(lldb) image list
and
/Mac/path/to/Build/Products/Debug-iphoneos% dwarfdump --uuid iOS-App.app/iOS-App
that will work on dylibs too.

Does your framework have parenthesis around the address? That's a sure sign that lldb can't find your symbols.

if the UUID in image list doesn't match the dwarfdump, then something has modified the executable before it ran and doesn't match your built products. We’re not sure if lipo might do that, which I see in your script but definitely check. Not much can be done if the debug-info no longer exists.

If you can find the right executable with a matching UUID on your disk, you can simply
(lldb) image add /Mac/path/to/DerivedData-asdfasdfadf/Products/Debug-iphoneos/iOS-App.app/Frameworks/Framework

Additionally, Xcode uses Spotlight to find symbols on your machine. To avoid constantly re-indexing while building, the Intermediates/ directory containing .o files and other place where debug information is stored was blacklisted. This happened fairly late in Xcode 9.0 so may be the reason your stuff was working before.

When I ran (lldb) image list at runtime, I saw that the UUID of my framework did not match that which was reported by dwarfdump at /Mac/path/to/Build/Products/Debug-iphoneos.

I ended up modifying my post-archive script to change which build directory it reads from when creating the framework. When I set my archive config to "Debug", it will read from Debug-iphoneos now. When I set it to "Release" it reads from ${BUILD_DIR}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}

# NOTE: This script creates a universal framework (device and simulator). However, *** for this to work: a Simulator target must be built first, and then Archive on the Device ***

BUILD_PRODUCTS="${SYMROOT}/../../../../Products"
SIM_PATH="${BUILD_PRODUCTS}/Debug-iphonesimulator/${TARGET_NAME}.framework"
if [ "${CONFIGURATION}" = "Debug" ]; then
DEV_PATH="${BUILD_PRODUCTS}/Debug-iphoneos/${TARGET_NAME}.framework"
elif [ "${CONFIGURATION}" = "Release" ]; then
DEV_PATH="${BUILD_DIR}/${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}/${TARGET_NAME}.framework"
fi
DEST_PATH="${PROJECT_DIR}/../Frameworks/${TARGET_NAME}.framework"

rm -rf "${DEST_PATH}"
mkdir "${DEST_PATH}"
cp -r "${DEV_PATH}/" "${DEST_PATH}/"
rm -f "${DEST_PATH}/${TARGET_NAME}"
cp -Rn "${SIM_PATH}/Modules/" "${DEST_PATH}/Modules/"

lipo -create "${SIM_PATH}/${TARGET_NAME}" "${DEV_PATH}/${TARGET_NAME}" -output "${DEST_PATH}/${TARGET_NAME}"

If the paths are confusing, I don't blame you. Essentially, workspace looks like:

RootDirectory
|__SampleApp
|__SampleApp.xcodeproj
|__Frameworks
|__MyFramework.framework
|__AnotherFramework.framework
|__MyFramework
|__MyFramework.xcworkspace
|__MyFramework.xcodeproj
|__Podfile (etc..)


Related Topics



Leave a reply



Submit