Instruments

RSS for tag

Instruments is a performance-analysis and testing tool for iOS, iPadOS, watchOS, tvOS, and macOS apps.

Instruments Documentation

Posts under Instruments tag

87 Posts
Sort by:
Post not yet marked as solved
1 Replies
1k Views
Hi, Machine: M1 sonoma 14.1.1 At my test I am using macOS shipped lib of curl, and its default LibreSSL, that is: curl 8.1.2 (x86_64-apple-darwin23.0) libcurl/8.1.2 (SecureTransport) LibreSSL/3.3.6 zlib/1.2.12 nghttp2/1.55.1 I am getting memory leaks while running the following test: void CallCurl() { CURL *hnd; hnd = curl_easy_init(); curl_easy_setopt(hnd, CURLOPT_URL, "https://www.google.com"); curl_easy_perform(hnd); curl_easy_cleanup(hnd); } I track the leaks with macOS instruments, and I see that all leaks are from libcrypto. The leaks are measured after curl_easy_cleanup. Examples for the leaks stack frames: serialize_ECPublicKey ECDSA_do_verify_new ossl_ecdsa_verify EVP_DigestVerifyFinal tls13_server_certificate_verify_recv tls13_handshake_perform tls13_legacy_connect ossl_connect_common ssl_cf_connect cf_setup_connect cf_hc_connect Curl_conn_connect multi_runsingle curl_multi_perform curl_easy_perform CallCurl() main start ccMallocECCryptor CCECCryptorImportKey ECDSA_do_verify_new ossl_ecdsa_verify EVP_DigestVerifyFinal tls13_server_certificate_verify_recv tls13_handshake_perform tls13_legacy_connect ossl_connect_common ssl_cf_connect cf_setup_connect cf_hc_connect Curl_conn_connect multi_runsingle curl_multi_perform curl_easy_perform CallCurl() main start ccMallocECCryptor CCECCryptorImportKey ECDSA_do_verify_new ossl_ecdsa_verify EVP_DigestVerifyFinal tls13_server_certificate_verify_recv tls13_handshake_perform tls13_legacy_connect ossl_connect_common ssl_cf_connect cf_setup_connect cf_hc_connect Curl_conn_connect multi_runsingle curl_multi_perform curl_easy_perform CallCurl() main start Any you familiar with memory leaks issues at curl that is shipped with macOS? Is there a workaround? Thx, Moshe.
Posted
by Mos123.
Last updated
.
Post not yet marked as solved
3 Replies
2.1k Views
Hi, I use Xcode Instruments to Profile my app, but I don't know why Instruments can not find the right source code path, like the screensh ot shows, the path is wrong, what is ? it looks like a placeholder, is xcode forgetting to replace this placeholder with real file name? anyone know how to fix this? thank you in advance
Posted Last updated
.
Post marked as solved
3 Replies
1.4k Views
Since version 14, Instruments cannot find the binary to show disassembly of executable or library. It says: Error - Binary file for selected symbol is expected to be here: /Users/<user>/Library/Developer/Xcode/DerivedData/<project>/Build/Products/Release/<project>. The thing is that the path shown by Instruments is actually the right one, and of course the binary exists in this directory. Am I missing something somewhere ?
Posted
by chubert.
Last updated
.
Post not yet marked as solved
1 Replies
113 Views
Hi! I watched WWDC 2019 Optimizing App Launch video and can't see the Lifecycle phases when I Profile my App. I'm using Xcode 15.2 with Instruments 15.2, and SwiftUI as UI framework. Here is a screenshot of what I get. It's there another tool or another way to get this information? Thanks! Alfonso.
Posted
by amestre.
Last updated
.
Post not yet marked as solved
0 Replies
132 Views
I asked this on StackOverflow too, but did not get a response. Copying verbatim (images might not work as expected). Short question: which instructions other than floating point arithmetic instructions like fmul, fadd, fdiv etc are counted under the hardware event INST_SIMD_ALU in XCode Instruments? Alternatively, how can I count the number of floating point operations in a program using CPU counters? I want to measure/estimate the FLOPs count of my program and thought that CPU counters might be a good tool for this. The closest hardware event mnemonic that I could find is INST_SIMD_ALU, whose description reads. Retired non-load/store Advanced SIMD and FP unit instructions So, as a sanity check I wrote a tiny Swift code with ostensibly predictable FLOPs count. let iterCount = 1_000_000_000 var x = 3.1415926 let a = 2.3e1 let ainv = 1 / a // avoid inf for _ in 1...iterCount { x *= a x += 1.0 x -= 6.1 x *= ainv } So, I expect there to be around 4 * iterCount = 4e9 FLOPs. But, on running this under CPU Counters with the event INST_SIMD_ALU I get a count of 5e9, 1 extra FLOP per loop iteration than expected. See screenshot below. dumbLoop is the name of the function that I wrapped the code in. Here is the assembly for the loop +0x3c fmul d0, d0, d1 <---------------------------------- +0x40 fadd d0, d0, d2 | +0x44 fmov d4, x10 | +0x48 fadd d0, d0, d4 | +0x4c fmul d0, d0, d3 | +0x50 subs x9, x9, #0x1 | +0x54 b.ne "specialized dumbLoop(_:initialValue:)+0x3c" --- Since it's non-load/store instructions, it shouldn't be counting fmov and b.ne. That leaves subs, which is an integer subtraction instruction used for decrementing the loop counter. So, I ran two more "tests" to see if the one extra count comes from subs. On running it again with CPU Counters with the hardware event INST_INT_ALU, I found a count of one billion, which adds up with the number of loop decrements. Just to be sure, I unrolled the loop by a factor of 4, so that the number of loop decrements becomes 250 million from one billion. let iterCount = 1_000_000_000 var x = 3.1415926 let a = 2.3e1 let ainv = 1 / a // avoid inf let n = Int(iter_count / 4) for _ in 1...n { x *= a x += 1.0 x -= 6.1 x *= ainv x *= a x += 1.0 x -= 6.1 x *= ainv x *= a x += 1.0 x -= 6.1 x *= ainv x *= a x += 1.0 x -= 6.1 x *= ainv } print(x) And it adds up, around 250 million integer ALU instructions, and the total ALU instructions is 4.23 billion, somewhat short of the expected 4.25 billion. So, at the moment if I want to count the FLOPs in my program, one estimate I can use is INST_SIMD_ALU - INST_INT_ALU. But, is this description complete, or are there an other instructions that I might spuriously count as floating point operations? Is there a better way to count the number of FLOPs?
Posted
by cku.
Last updated
.
Post not yet marked as solved
2 Replies
166 Views
I am interested in adding signposts to an existing large application that was written in .NET compiled in VisualStudio for MacOS so that I can isolate portions of the application in instruments. It seems like it's straightforward to do this in C++ but I couldn't figure out how to do it, perhaps there is a way via dll invoke? Appreciate any suggestions.
Posted
by Brantolio.
Last updated
.
Post marked as solved
23 Replies
5.5k Views
When trying to profile any process with the Instruments CPU Profiler I get this message: (Before run started) No allocated PMI record. Not sure what to do here. I tried other instruments like time profile and that works fine so not sure what to do here... Didn't find any people having similar issues when googling so I'm hoping someone here can help me out. Im using a m1 max 14 inch macbook pro with macOS 12.3 and instruments 13.0 (13A1030d)
Posted
by Ruben-elk.
Last updated
.
Post not yet marked as solved
5 Replies
568 Views
The Points of Interest Instrument is not recording any data when profiling my application on Sonoma. The same code is producing signposts when profiling on a computer running Sonoma. Here's what how the instruments screen looks: Note that there are no Points of Interest being recorded. I created a new project for this test and added code to emit signposts whenever the application becomes active or goes into the background. This is the code I'm using for the test (copied from forum post from a year ago). import os.signpost @main class AppDelegate: NSObject, NSApplicationDelegate { var window: NSWindow? var blackWindow: NSWindow? var alertWindow: NSWindow? static var originalAppDelegate: AppDelegate! var signposter: OSSignposter var signpostInterval: OSSignpostIntervalState? func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { return true } override init() { signposter = OSSignposter(subsystem: Bundle.main.bundleIdentifier ?? "unknown", category: .pointsOfInterest) super.init() assert(signposter.isEnabled) signposter.emitEvent(#function) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } func applicationWillResignActive(_ notifiction: Notification) { guard let interval = signpostInterval else { assertionFailure("no interval") return } print("backgrounding, ending active state") signposter.endInterval("active", interval) } func applicationDidBecomeActive(_ notification: Notification) { print("begin active state") signpostInterval = signposter.beginInterval("active") } } Is anyone else having this problem? I tested this on my development machine (Retina 5K, 27-inch, 2019) running Sonoma 14.2.1. The problem occurs even with a clean install of Sonoma onto an external boot disk. The same code produces this screenshot when running in Ventura 13.6.1.
Posted Last updated
.
Post not yet marked as solved
1 Replies
237 Views
Hello everyone, Our iOS app is taking too long to launch. On checking the launch profile, we are seeing that most of the launch time is being spent in applying fixups which is taking more than a second and at times even more to complete. Our deployment target is iOS 15+. We have checked using dyld_info that our binary uses chained fixups. Since chained fixups are enabled, page-in linking should also be enabled for our app as per this WWDC session. Can someone please help us understand why the fixups application is taking this long and how can we improve it? Thanks.
Posted Last updated
.
Post not yet marked as solved
2 Replies
223 Views
I am using the Leaks instrument, and it has identified a bunch of 32 and 48 byte "Malloc" leaks. I would like to see a hex dump of some (or all) of those areas. I think if I can see what is in them I can get a better idea about what is triggering the leak. I'm pretty sure it is a real leak. What is the easy way to do this? Can it be done inside instruments, or do I need to run my app under instruments and also attach via lldb and hexdump from lldb? (can I attach lldb and instruments at the same time?) If it matters I'm debugging an iPadOS app, and it is written in Swift plus ObjC, plus ObjC++, oh, and some straight C++.
Posted Last updated
.
Post not yet marked as solved
5 Replies
695 Views
When using Instruments in Xcode 15.3 on macOS Sonoma 14.3.1 symbols from system frameworks are not displaying. I've tried creating a template "App" project and running it on the iOS 17.4 simulator without any code changes and still am not seeing symbols so I can be sure it's not unique to my real-world project build settings. If I install Xcode 15.0 and run the same build in the same 17.4 simulator using Instruments 15.0 it shows thread names and symbols for UIKit and other frameworks but is still missing SwiftUI symbols. Instruments 15.3 Instruments 15.0 I've spent 2 days trying to narrow down why I couldn't debug my app and even deleted all my partitions and reinstalled macOS which didn't fix the issue.
Posted Last updated
.
Post not yet marked as solved
3 Replies
487 Views
Hello, This relates to NSTrackingDomains for Privacy Manifest. Following doc here https://developer.apple.com/documentation/xcode/detecting-when-your-app-contacts-domains-that-may-be-profiling-users. (Also, I'm quite new to using the Network Instrument). I'm not seeing any "Points of Interest" but I know my app has domains that should be shown as "Faults". Do I need to os_log to my Objective-C codebase. I don't have access to the code of various 3rd party SDKs. The doc mentioned above made it sound like these domains should automagically appear. Thanks!
Posted Last updated
.
Post marked as solved
10 Replies
1.8k Views
I have a performance issue with a Mac SwiftUI app. Using instruments I see hangs reported. When I zero in on a hang I see that the time profiler reports most of the hang -- in one example 658 out of 687 ms -- being in 'static AppName.$main() [inlined]'. I think that is saying my app is busy, but busy doing what? The "hangs" are related to SwiftUI table processing. User experience is something like this: select an item, see the view changes based upon selection show up a second or two later. The duration of the hang increases with the number of items in the table. I'm testing with 100 ~ 1200 table entries.
Posted
by marchyman.
Last updated
.
Post marked as solved
3 Replies
347 Views
I have an iOS app that uses os_signpost API for instrumentation. When I profile it from Xcode on real iOS device, it works as expected. When I profile its macCatalyst variant (using the identical code) on the same Mac where Xcode is running, the os_signpost Instrument does not show anything, not even the Apple provided signposts that are otherwise visible on the iOS. How do I make it work?
Posted
by enodev.
Last updated
.
Post not yet marked as solved
8 Replies
997 Views
Hello, I am trying to debug Swift Concurrency codes by using Swift Concurrency Instruments. But in our project which has been maintained for a long time, Swift Concurrency Instruments seems not working. Task { print("async code") await someAsyncFunction() } When I run Swift Concurrency Instruments with the above codes in our project, I could check that the print works well by checking stdout/stderr Instruments, but there are no records on Swift Concurrency Instruments. But in the small simple sample project, I checked that Swift Concurrency Instruments works well. Are there any settings that I need to do for the legacy project to debug Swift Concurrency?
Posted
by presto95.
Last updated
.
Post not yet marked as solved
7 Replies
3.5k Views
Hi, I've run an Instruments network capture of our iOS app and the Points of Interest track lists faults due to undisclosed tracking domains. For example app-measurement.com which is used by Firebase causes the fault: Fault: app-measurement.com is not listed in your app's NSPrivacyTrackingDomain key in any privacy manifest. It may be following users across multiple apps and websites to create a profile about users of apps that contact this domain. However my PrivacyInfo.xcprivacy file contains (API and Nutrition info omitted): NSPrivacyTracking: true NSPrivacyTrackingDomains: app-measurement.com So I'm surprised the fault is still occurring. Is it because the call is coming from a 3rd party SDK (Firebase)? I'll be removing this entry once a compliant Firebase SDK is released but figured it should still work. I've checked that the IPA contains PrivacyInfo.xcprivacy, and that I'm able to generate a privacy report. I'm using Xcode 15.0, iOS 17.1.
Posted
by sbenfold.
Last updated
.
Post not yet marked as solved
1 Replies
354 Views
I'm introducing some SwiftUI into a primarily UIKit app and have noticed that, as soon as a SwiftUI view is presented / pushed to the nav stack in its hosting view controller, the memory graph shows a number of Swift closure context (unknown layout) entries under an <unknown> header. These entries persist after the SwiftUI view has been popped from the navigation stack. Is this cause for concern? I don't think it represents a memory leak within my app, because the entries are grouped under <unknown> as opposed to my app name. But I'm not entirely sure why they exist (and crucially, why they persist). It's possible to observe this behaviour with a really simple demo app. Just push the following view: struct ViewController02: View { var body: some View { Text("Hello, world!") } } onto a navigation stack: self.navigationController?.pushViewController(UIHostingController(rootView: ViewController02()), animated: true) Any advice / guidance / reassurance would be much appreciated. There can be a considerable number of these entries but I can't see how I could be causing a retain cycle.
Posted Last updated
.
Post not yet marked as solved
0 Replies
232 Views
Hi! Is there a reason why trace's *-profile tables (time-profile, cpu-profile, counters-profile) always use an instruction pointer value that is 1 byte larger than what should be a true instruction pointer value? Odd valued IPs on Apple M2 are definitely incorrect as instructions have to be word-aligned. It's also worth mentioning that addresses in "source" tables ("time-sample" for "time-profile", "kdebug-counters-with-pmi-sample" for "cpu-profile" and "counters-profile") are correct (or, at least, are correctly aligned aligned). Here's an example: % xctrace version xctrace version 15.2 (15C500b) # run recording % xctrace record --template "Time Profile" --output TP.trace --launch /bin/dd if=/dev/random of=/dev/null bs=1024 count=1048576 # extract "source" table % xctrace export --input TP.trace --xpath='/trace-toc/run[1]/data/table[@schema="time-sample"]' > tp.time-sample.xml # extract "derived" table % xctrace export --input TP.trace --xpath='/trace-toc/run[1]/data/table[@schema="time-profile"]' > tp.time-profile.xml % xmllint --xpath '//row[1]' tp.time-sample.xml <row><sample-time id="1" fmt="00:00.040.502">40502000</sample-time><thread id="2" fmt="Main Thread 0x37c2d0a (dd, pid: 32471)"><tid id="3" fmt="0x37c2d0a">58469642</tid><process id="4" fmt="dd (32471)"><pid id="5" fmt="32471">32471</pid><device-session id="6" fmt="TODO">TODO</device-session></process></thread><core id="7" fmt="CPU 4 (P Core)">4</core><thread-state id="8" fmt="Running">Running</thread-state><sentinel/><kperf-bt id="9" fmt="PC:0x1863149fc, 3 frames, 1 regs, pid: 32471"><text-addresses id="10" fmt="frag 1717">6546645708 6546360308 0</text-addresses><text-address id="11" fmt="0x1863149fc">6546344444</text-address><process ref="4"/><register-content id="12" fmt="0x2e4c00018635e2cc">3336041430521340620</register-content></kperf-bt><time-sample-kind id="13" fmt="Timer Fired">0</time-sample-kind></row> % xmllint --xpath '//row[1]' tp.time-profile.xml <row><sample-time id="1" fmt="00:00.040.502">40502000</sample-time><thread id="2" fmt="Main Thread 0x37c2d0a (dd, pid: 32471)"><tid id="3" fmt="0x37c2d0a">58469642</tid><process id="4" fmt="dd (32471)"><pid id="5" fmt="32471">32471</pid><device-session id="6" fmt="TODO">TODO</device-session></process></thread><process ref="4"/><core id="7" fmt="CPU 4 (P Core)">4</core><thread-state id="8" fmt="Running">Running</thread-state><weight id="9" fmt="1.00 ms">1000000</weight><backtrace id="10"><frame id="11" name="0x1863149fd" addr="0x1863149fd"><binary id="12" name="dyld" UUID="324E4AD9-E01F-3183-B09F-3E20B326643A" arch="arm64e" load-addr="0x186313000" path="/usr/lib/dyld"/></frame><frame id="13" name="0x18635e2cc" addr="0x18635e2cc"><binary ref="12"/></frame><frame id="14" name="start" addr="0x1863187f4"><binary ref="12"/></frame></backtrace></row> As you can see, <kperf-bt id="9" fmt="PC:0x1863149fc, 3 frames, 1 regs, pid: 32471"> refers to a properly aligned address, but the address from <backtrace id="10"><frame id="11" name="0x1863149fd" addr="0x1863149fd">... is off by one. It seems like only an address from the top frame is incorrect, as others are aligned properly. The same issue exists for "CPU Profile" and "CPU Counters" instruments and could be reproduced on macOs running on both x86-64 and Apple-Silicon CPUs.
Posted
by fzhinkin.
Last updated
.