Fix Apple Watch Auto Unlock

Stolen from here from LongZheng

I’ve finally fixed it! I found a bunch of errors related to “AutoUnlock” in the Console that was hinting to me that there was some invalid state on my Mac with keys and plists not being reset properly. After clearing/resetting them, I can now successfully pair my watchOS 7 Series 3 to macOS 10.15.6.

Steps (follow at your own discretion)

  1. Open “Keychain Access” -> Passwords.
  2. In “View”, enable “Show Invisible Items”

  3. Search for “Auto Unlock”
  4. You should see a whole bunch of application passwords for “Auto Unlock: XXXX’s …”
  5. Select all records and delete (this will reset/disable auto unlock on other Macs if you use multiple Macs)
  6. Whilst still in “Keychain Access”, search for “AutoUnlock” (no space)
  7. There should be 4 entries for “tlk” “tlk-nonsync” “classA” “classC”
  8. Select 4 records and delete (don’t worry if they re-appear, the system repairs this automatically)
  9. Open “Finder” and navigate to “~/Library/Sharing/AutoUnlock”
  10. There should be two files “ltk.plist” and “pairing-records.plist”
  11. Delete both files
    (Some users have reported better success restarting macOS at this stage)
  12. Open “System Preferences” and try enabling auto unlock. You may need to enable it twice, the first attempt will fail.


UIWindow* window = [[UIApplication sharedApplication] keyWindow];
UIView* snapshotView = [[UIView alloc] init];
snapshotView.translatesAutoresizingMaskIntoConstraints = false;
[window addSubview:snapshotView];
[NSLayoutConstraint activateConstraints:@[
[snapshotView.topAnchor constraintEqualToAnchor:window.topAnchor],
[snapshotView.leadingAnchor constraintEqualToAnchor:window.leadingAnchor],
[snapshotView.trailingAnchor constraintEqualToAnchor:window.trailingAnchor],
[snapshotView.bottomAnchor constraintEqualToAnchor:window.bottomAnchor]
snapshotView.backgroundColor = [UIColor blueColor];
[UIView animateWithDuration:0.2
snapshotView.alpha = 0;
completion:^(BOOL finished) {
[snapshotView removeFromSuperview];

Rebase without re-checkout

TL;DR: when using multiple branches, prefer to use “git rebase –onto origin/master origin/master ${branch}” if you want to checkout and then rebase a branch.

Let’s say you have the working history:

       /-*-* A
*-*-*-*-*-*-* origin/master
        \-*-*-* B

and you want to push the branch A because your CL has been approved. You have to rebase A on origin/master, then build and run test and do git cl push. Once this is done, you now have the following history:

*-*-*-*-*-*-*-@ origin/master (after push)
        \-*-*-* B

Now you want to go back to work on B. Until recently, I used the following commands (striked-ed out as I now consider them broken):

$ git checkout B
$ git rebase origin/master

This has the disadvantage of marking as dirty all the files that are in the delta between the point B diverged from origin/master in addition to all the files modified in B since the branch was created.

There is however a better way:

$ git rebase –onto origin/master origin/master B

This will still rebase B on top of origin/master, but will not checkout B first, so only the files that have been modified in B will be touched and considered dirty by the build. Depending on how large the change in origin/master have been, this can be the difference between rebuilding thousand of files and rebuilding just a few tens.

How to print Chromium string16 values from lldb using python scripts

I found this here: with a minor tweak of if -> elif

Thanks stack overflow!

Python file:
$ cat ~/work/lldbscripts/
import lldb
def unsignedshortptr_SummaryProvider(valobj, dict):
e = lldb.SBError()
s = u'"'
if valobj.GetValue() != 0:
i = 0
newchar = -1
while newchar != 0:
# read next wchar character out of memory
data_val = valobj.GetPointeeData(i, 1)
size = data_val.GetByteSize()
if size == 1:
newchar = data_val.GetUnsignedInt8(e, 0) # utf-8
elif size == 2:
newchar = data_val.GetUnsignedInt16(e, 0) # utf-16
elif size == 4:
newchar = data_val.GetUnsignedInt32(e, 0) # utf-32
return "" % size
return ''
i = i + 1
# add the character to our string 's'
if newchar != 0:
s = s + unichr(newchar)
s = s + u'"'
return s.encode('utf-8')

init file:

$ cat .lldbinit
command script import /Users/justincohen/work/lldbscripts/
type summary add -F unsignedshortptrsummary.unsignedshortptr_SummaryProvider "unsigned short *"

Gives you:

(lldb) p new_text
(string16) $5 = {
(std::basic_string >::_Alloc_hider) _M_dataplus = {
(unsigned short *) _M_p = 0x110625cc "This is a string16!!"

Git clean. No seriously, clean it.

Working on Chrome, there are lots of dependencies that get pulled, and when I make untracked temporary changes in those dependancies sometimes I just want everything back to normal. So, here’s the scorched earth method:

git clean -f -f -x -d

This blows away everything git doesn’t know about. Then I do another clean dependency pull and I’m back to the beginning!

mach.h, dumping vm info

#import "mach/mach.h"
- (void)logTimer {
task_basic_info info;
mach_msg_type_number_t size = sizeof(info);
kern_return_t kerr = task_info(mach_task_self(),
if ( kerr == KERN_SUCCESS ) {
NSLog(@"task_info: %d.2MB\n", info.resident_size / 1048576);
else {
NSLog(@"task_info failed with error %d ( 0x%08d ), '%s'\n",
kerr, kerr, mach_error_string(kerr));

Another weird git problem

Lately whenever I have to rebase I get a weird error about how I have a dirty tree and need to commit files.

Falling back to patching base and 3-way merge...
error: Your local changes to the following files would be overwritten by merge:

Please, commit your changes or stash them before you can merge.
Failed to merge in the changes.

Well this is a dirty lie, and the problem appears to be related to hardlinking changing the ctime of the source file and confusing git into thinking that the files need to be re-checked-out. Bottom line, the fix is here:

git config --global core.trustctime false

Recent git branches

Sometimes I forget to delete my old git branches, and I forget which is what and who is how. And so on and so forth. So I do this!:

git reflog --date=local --all

This outputs a nifty list of all the recent commits and which branches they were too. w00t.

iOS timing

Again, do as I say not as I do. Here’s a quick thing I like to do:

NSTimeInterval start = CACurrentMediaTime();
NSTimeInterval end = CACurrentMediaTime();
NSLog(@"%f", end-start);

git format-patch and git am

Occasionally I need to send a git patch between computers. Yes, I know there are more efficient ways of doing this, but occasionally it needs to happen. So here’s how I do it:

git format-patch --binary master.. --stdout > the.patch

and how to apply it:

git am --signoff < the.patch