Skip to content

Instantly share code, notes, and snippets.

@NSEGeorge
Created November 3, 2018 14:21
Show Gist options
  • Save NSEGeorge/688a4a8eaaaec98f0e59507ca91724f5 to your computer and use it in GitHub Desktop.
Save NSEGeorge/688a4a8eaaaec98f0e59507ca91724f5 to your computer and use it in GitHub Desktop.
Swift implementation of function for measuring application launch time. Call it from start or end didFinishLaunchingWithOptions.
import UIKit
class LaunchTimeMeasurer {
private let pid = ProcessInfo().processIdentifier
private var currentTime = timeval(tv_sec: 0, tv_usec: 0)
private var bootTime = timeval()
private var size = MemoryLayout<kinfo_proc>.stride
private var mib: [Int32]
init() {
mib = [CTL_KERN, KERN_PROC, KERN_PROC_PID, pid]
}
func processLaunchTime() -> Double {
sysctl(&mib, u_int(mib.count), &bootTime, &size, nil, 0)
gettimeofday(&currentTime, nil)
return toSeconds(time: currentTime) - toSeconds(time: bootTime)
}
private func toSeconds(time: timeval) -> Double {
let microsecondsInSecond = 1000000.0
return Double(time.tv_sec) + Double(time.tv_usec) / microsecondsInSecond
}
}
@RagulChandra
Copy link

malloc: Heap corruption detected, free list is damaged at 0x60000138d090
*** Incorrect guard value: 5643587033499
(6555,0x10eb575c0) malloc: *** set a breakpoint in malloc_error_break to debug

I am getting the above error while executing the code.Can you please help to resolve this?

@eschos24
Copy link

eschos24 commented May 9, 2020

I'm having an issue implementing this code. After the sysctl call on line 15 it corrupts the stack and upon returning it gives me the following error: "error: memory read failed for 0x0". I stepped through the code and that line is where it happens. Up until that point I can see the stacktrace just fine, but as soon as that line executes it's gone. Even though I get valid values back from calling toSeconds: it just crashes the app. Any help you might be able to give me would be greatly appreciated!

@eschos24
Copy link

eschos24 commented May 12, 2020

I was able to figure out what was wrong, and it might help @RagulChandra too. sysctl takes a kinfo_proc, not a timeval. Using a timeval will still return the correct value, but causes memory corruption later on in your app's life cycle.

Here are the modifications that should be made to avoid memory corruption:

...
private var kp = kinfo_proc()  // kp instead of bootTime
...

func processLaunchTime() -> Double {
  sysctl(&mib, u_int(mib.count), &kp, &size, nil, 0)
  gettimeofday(&currentTime, nil)

  let bootTime = kp.kp_proc.p_un.__p_starttime  // this is a timeval struct

  return toSeconds(time: currentTime) - toSeconds(time: bootTime)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment