Tag: troubleshooting

  • How I Saved My MacBook Pro From Bad RAM

    How I Saved My MacBook Pro From Bad RAM

    Oh boy, how did we end up here?

    When the first macOS Sequoia public beta came out, I went ahead and installed it on my 2019 Intel MacBook Pro. I’ve never had a problem with public betas, and usually try them out.

    Well, this time something went wrong. I don’t remember the details, but the install crashed, froze, or borked somehow near the end. I restarted and it seemed to finish.

    … but we wouldn’t be here if that were the end of the story…

    Something felt off, and whenever I rebooted my MacBook Pro, anything I did reverted itself to back to the end of the public beta install. I was stuck in some sort of disk snapshot mode. I tried repairing the disk, I tried rebooting into single user mode and fixing things, all sorts of stuff I tried to think of, stuff I googled, and stuff I dangerously got from ChatGPT. Nothing would fix it to where I could permanently modify my drive anymore.

    So I did what anyone would do–I backed up my important files and completely reformatted the drive and did a fresh install once the final version of Sequoia came out.

    And that worked, and things were fine. Except for some random crashes every now and then. Sometimes a Firefox tab would crash. Sometimes the machine would not come out of sleep. Sometimes Messages would not sync from iCloud. Sometimes entire programs would crash.

    I had just assumed it was the perils of the new macOS on older hardware, and I kept going forward… 15.1 came out, and problems persisted… 15.2…. 15.3… well, by now any bugs should be fixed! Something is wrong. I of course understand that these random crashes feel a lot like bad memory, but I was in denial. The MacBook had soldered RAM and there was nothing I could 😭

    I first went with Memtester as a quick test, just to confirm that my RAM is fine:

    $ sudo memtester 16G 2
    Password:
    memtester version 4.7.0 (64-bit)
    Copyright (C) 2001-2024 Charles Cazabon.
    Licensed under the GNU General Public License version 2 (only).
    
    pagesize is 4096
    pagesizemask is 0xfffffffffffff000
    want 16384MB (17179869184 bytes)
    got  16384MB (17179869184 bytes), trying mlock ...locked.
    Loop 1/2:
      Stuck Address       : testing   1FAILURE: possible bad address line at offset 0x0000000254c27038.
    Skipping to next test...
      Random Value        : FAILURE: 0x06bf7b9befebc9e5 != 0x0ebf7b9befebc9e5 at offset 0x0000000054c27840.
    FAILURE: 0x2106487df0007127 != 0x2906487df0007127 at offset 0x0000000054c27030.
    FAILURE: 0x2106487df0007127 != 0x2906487df0007127 at offset 0x0000000054c27038.
    FAILURE: 0x2106487df0007127 != 0x2906487df0007127 at offset 0x0000000054c28238.
      Compare XOR         :   Compare SUB         : ok
    FAILURE: 0x0400ed73c8282b4d != 0x0c00ed73c8282b4d at offset 0x0000000054c27038.
    FAILURE: 0x0400ed73c8282b4d != 0x0c00ed73c8282b4d at offset 0x0000000054c28238.
      Compare MUL         : FAILURE: 0x0000000000000002 != 0x0800000000000002 at offset 0x0000000054c27030.
    FAILURE: 0x0000000000000002 != 0x0800000000000002 at offset 0x0000000054c27038.
    FAILURE: 0x0000000000000002 != 0x0800000000000002 at offset 0x0000000054c28238.
      Compare DIV         :   Compare OR          : ok
      Compare AND         : ok
      Sequential Increment: ok
      Solid Bits          : testing   0FAILURE: 0x0000000000000000 != 0x0800000000000000 at offset 0x0000000054c27038.
    FAILURE: 0x0000000000000000 != 0x0800000000000000 at offset 0x0000000054c28238.
      Block Sequential    : testing   0FAILURE: 0x0000000000000000 != 0x0800000000000000 at offset 0x0000000054c27030.
    FAILURE: 0x0000000000000000 != 0x0800000000000000 at offset 0x0000000054c27038.
    FAILURE: 0x0000000000000000 != 0x0800000000000000 at offset 0x0000000054c28238.
      Checkerboard        : testing   1FAILURE: 0x5555555555555555 != 0x5d55555555555555 at offset 0x0000000054c27038.
    FAILURE: 0x5555555555555555 != 0x5d55555555555555 at offset 0x0000000054c28238.
      Bit Spread          : testing  57FAILURE: 0xf5ffffffffffffff != 0xfdffffffffffffff at offset 0x0000000054c27038.
      Bit Flip            : testing   0FAILURE: 0x0000000000000001 != 0x0800000000000001 at offset 0x0000000054c27038.
    FAILURE: 0x0000000000000001 != 0x0800000000000001 at offset 0x0000000054c28238.
      Walking Ones        : setting   4Code language: PHP (php)

    I was nervous! There were failures! But I also knew that testing live in the OS isn’t perfect, so maybe there was a chance! I whipped up a flash drive with Memtest86 to prove that my memory was still good. Phew.

    Yeah… about that…

    I had a serious problem! This machine is still perfectly fine. I had to make a choice:

    1. I could try to repair it myself. I’ve never done any BGA work myself, but I’ve seen plenty of it done and honestly how hard could it be? *nervous chuckle*
    2. I could pay to get this fixed. That’s the safest solution.
    3. I could install Linux and use badram to just ignore the problem. The problem with this is that I’d lose all of the MacOS magic with the ecosystem.

    Alright, so let’s go with the safest option first. I fired off a quote request to Rossman Repair Group, who seem to be the best at this stuff.

    *sad trombone noises*

    Alright, so the choices are clear. I can either start hacking away at my hardware or try some software based solutions. I knew that Linux had a nice badram option with Grub, so I started searching around to see if there was any way at all to get that working for macOS.

    I searched and continued to come up with nothing. There was no way that I could find to get badram to work with macOS. Bummer.

    …there’s a glimmer of hope though…

    In my many searches, I ran across this project:

    Could this be what I need? Basically a badram type functionality for macOS? Sweet! Alright, let’s try this out.

    So I can’t just magically install this software. It’s part of the EFI boot loader, so we need to install it there.

    BUT WAIT THERE’S MORE. From what I was able to tell, I needed an EFI shell because macOS doesn’t have a built-in way to blacklist bad RAM addresses at boot like Linux’s badram does. So the plan was simple:

    1. Install an EFI shell that would let me run the RAM-disabling utility before macOS boots.
    2. Set up rEFInd as a boot manager to automate the process.
    3. Write an EFI shell script to block the bad RAM every time the system starts.


    First, I grabbed the TianoCore UEFI Shell (aka Shell_Full.efi) from the official TianoCore repository. I copied it onto my EFI partition, so it could be accessed at boot. It went a little something like this:

    sudo mkdir -p /Volumes/ESP
    sudo mount -t msdos /dev/disk0s1 /Volumes/ESP
    sudo cp ~/Downloads/Shell_Full.efi /Volumes/ESP/EFI/tools/ShellX64.efiCode language: JavaScript (javascript)

    This meant that at boot, I’d have an EFI shell available to execute commands manually.

    Rather than having to manually select the EFI shell every time, I installed rEFInd to make life easier. This boot manager would allow me to configure an automatic script to disable the bad RAM before macOS even loads.


    After installing rEFInd and mounting the EFI partition again, I placed the RAM-disabling utility (disable-ram-area.efi) into the correct folder by running sudo cp disable-ram-area.efi /Volumes/ESP/EFI/refind/


    Now came the fun part—writing a script (startup.nsh) that would automatically execute disable-ram-area.efi with the right parameters every time the system booted.

    My bad RAM addresses (from MemTest86) were 0x1608F80780x1628FFCB4 (~32MB). To ensure alignment, I slightly expanded the range to 0x1608F70000x162A00000. This ensures that the entire faulty region is covered and avoids instability caused by page misalignment.

    My final startup.nsh script looked like this:

    echo Running disable-ram-area.efi
    
    # Locate the EFI partition (fs0:)
    set DISK fs0
    
    # Check if disable-ram-area.efi exists
    if not exist %DISK%\EFI\refind\disable-ram-area.efi then
        echo ERROR: Could not find disable-ram-area.efi in /EFI/refind/. Exiting...
        exit
    endif
    
    echo Found disable-ram-area.efi on %DISK%
    stall 1000000
    
    # Run the memory fix
    %DISK%\EFI\refind\disable-ram-area.efi 0x1608F7000 0x162A00000
    
    echo Starting macOS
    stall 1000000
    
    # Locate macOS bootloader (fs3:)
    set MACOS fs3
    
    # Check if boot.efi exists
    if not exist %MACOS%\System\Library\CoreServices\boot.efi then
        echo ERROR: Could not find boot.efi in fs3:. Exiting...
        exit
    endif
    
    echo Found boot.efi on %MACOS%
    stall 1000000
    
    # Boot macOS
    %MACOS%\System\Library\CoreServices\boot.efiCode language: PHP (php)

    This script does the following:

    1. Finds the EFI partition (fs0:) where disable-ram-area.efi is stored.
    2. Runs disable-ram-area.efi with my calculated bad RAM range.
    3. Finds the correct fsX: partition that contains boot.efi (macOS bootloader).
    4. Boots macOS, now with the bad RAM disabled.

    After saving startup.nsh to /Volumes/ESP/EFI/refind/, I rebooted into rEFInd, selected “EFI Shell”, and ran:

    fs0:
    cd EFI/refind
    startup.nsh

    It worked! The script executed, disabled my bad RAM, and booted into macOS.

    To make sure this runs automatically every time I turn on my Mac, I edited refind.conf and added:

    menuentry "Boot macOS with Defective RAM Disabled" {
        loader /EFI/tools/ShellX64.efi
        options "fs0:\EFI\refind\startup.nsh"
    }Code language: JavaScript (javascript)


    And to set it as the default boot option, I updated:

    default_selection "Boot macOS with Defective RAM Disabled"Code language: JavaScript (javascript)


    Now, every time I boot up my Mac, it automatically disables the bad RAM before macOS loads! Huge win!

    Now, this is just my story, please don’t take this as a tutorial. I rebuilt the entire process I have done through some scribbled notes, open tabs, and browser histories. I may have missed things or gotten them wrong and I’m too lazy to remount my EFI partition to verify that the scripts I shared here are the final ones I actually used.

    But if you find yourself in a similar position, hopefully this helps you with your own process of trying to save your MacBook.

  • Capturing MacOS Settings Changes

    Capturing MacOS Settings Changes

    Let me get this right out. I upgraded to MacOS 15 beta and it totally borked my machine. I had to do a full, fresh reinstall.

    Totally my fault, and I should have prepared better.

    So now, I’m trying to remember to capture my personal settings so I can use a shell script to restore them in case of emergency with defaults

    With the help of ChatGPT and a lot of stupidity, I have created this:

    #!/bin/bash
    
    # Set the DEBUG flag (default is false)
    DEBUG=false
    
    # Define a function for logging debug information
    log() {
        if [ "$DEBUG" = true ]; then
            echo "$@"
        fi
    }
    
    # Define a function for running commands with error suppression unless DEBUG is true
    run_command() {
        if [ "$DEBUG" = true ]; then
            "$@"
        else
            "$@" 2>/dev/null
        fi
    }
    
    # Step 1: Define directories for temporary files
    before_dir="/tmp/before_defaults"
    after_dir="/tmp/after_defaults"
    mkdir -p "$before_dir" "$after_dir"
    
    # Step 2: Capture system-wide and global preferences
    
    echo "Reading user-specific global preferences..."
    run_command defaults read -g > "$before_dir/user_global_defaults.plist"
    
    echo "Reading system-wide global preferences..."
    run_command sudo defaults read -g > "$before_dir/system_global_defaults.plist"
    
    echo "Reading user-specific system preferences..."
    run_command defaults read > "$before_dir/user_system_defaults.plist"
    
    echo "Reading system-wide system preferences..."
    run_command sudo defaults read > "$before_dir/system_system_defaults.plist"
    
    # Step 3: Get all domains and capture their preferences with and without sudo
    echo "Reading defaults for all domains..."
    domains=$(run_command defaults domains)
    for domain in $domains; do
        log "Reading user-specific defaults for domain: $domain"
        run_command defaults read "$domain" > "$before_dir/${domain}_user_defaults.plist"
        
        log "Reading system-wide defaults for domain: $domain"
        run_command sudo defaults read "$domain" > "$before_dir/${domain}_system_defaults.plist"
    done
    
    # Step 4: Capture network settings (excluding Launch Services to reduce noise)
    echo "Capturing network settings..."
    run_command sudo cp /Library/Preferences/SystemConfiguration/preferences.plist "$before_dir/network_settings.plist"
    
    echo "Current preferences saved. Please make your changes now."
    echo "Press any key to continue once you've made the changes..."
    read -n 1 -s
    
    # Step 5: Capture updated defaults
    echo "Reading updated user-specific global preferences..."
    run_command defaults read -g > "$after_dir/user_global_defaults.plist"
    
    echo "Reading updated system-wide global preferences..."
    run_command sudo defaults read -g > "$after_dir/system_global_defaults.plist"
    
    echo "Reading updated user-specific system preferences..."
    run_command defaults read > "$after_dir/user_system_defaults.plist"
    
    echo "Reading updated system-wide system preferences..."
    run_command sudo defaults read > "$after_dir/system_system_defaults.plist"
    
    echo "Reading updated defaults for all domains..."
    for domain in $domains; do
        log "Reading updated user-specific defaults for domain: $domain"
        run_command defaults read "$domain" > "$after_dir/${domain}_user_defaults.plist"
        
        log "Reading updated system-wide defaults for domain: $domain"
        run_command sudo defaults read "$domain" > "$after_dir/${domain}_system_defaults.plist"
    done
    
    echo "Capturing updated network settings..."
    run_command sudo cp /Library/Preferences/SystemConfiguration/preferences.plist "$after_dir/network_settings.plist"
    
    # Step 6: Compare before and after to identify changes with unified diffs and output results directly
    
    echo "Comparing preferences and generating diffs..."
    
    # Global and system diffs
    echo "Comparing global and system preferences..."
    diff -u "$before_dir/user_global_defaults.plist" "$after_dir/user_global_defaults.plist" | sed '/^\s*$/d'
    diff -u "$before_dir/system_global_defaults.plist" "$after_dir/system_global_defaults.plist" | sed '/^\s*$/d'
    
    diff -u "$before_dir/user_system_defaults.plist" "$after_dir/user_system_defaults.plist" | sed '/^\s*$/d'
    diff -u "$before_dir/system_system_defaults.plist" "$after_dir/system_system_defaults.plist" | sed '/^\s*$/d'
    
    echo "Comparing Domain Specific"
    # Domain-specific diffs
    for domain in $domains; do
        # Only run diff if both user-specific files exist
        if [ -f "$before_dir/${domain}_user_defaults.plist" ] && [ -f "$after_dir/${domain}_user_defaults.plist" ]; then
            
            #echo "Comparing user-specific defaults for domain: $domain"
            diff -u "$before_dir/${domain}_user_defaults.plist" "$after_dir/${domain}_user_defaults.plist" | sed '/^\s*$/d'
        fi
    
        # Only run diff if both system-wide files exist
        if [ -f "$before_dir/${domain}_system_defaults.plist" ] && [ -f "$after_dir/${domain}_system_defaults.plist" ]; then
            #echo "Comparing system-wide defaults for domain: $domain"
            diff -u "$before_dir/${domain}_system_defaults.plist" "$after_dir/${domain}_system_defaults.plist" | sed '/^\s*$/d'
        fi
    done
    
    diff -u "$before_dir/network_settings.plist" "$after_dir/network_settings.plist" | sed '/^\s*$/d'
    
    # Step 7: Clean up temporary files (optional, currently commented out)
    #log "Cleaning up temporary files..."
    #run_command sudo rm -r "$before_dir" "$after_dir"
    
    echo "Comparison complete."
    Code language: Bash (bash)

    This will basically do a scan of all defaults settings it can find, wait for you to make changes, and then show you a diff of what has changed.

    For a bad example, I wanted to auto hide the dock:

    $ bash default-changes.sh
    Reading user-specific global preferences...
    Reading system-wide global preferences...
    Reading user-specific system preferences...
    Reading system-wide system preferences...
    Reading defaults for all domains...
    Capturing network settings...
    Current preferences saved. Please make your changes now.
    Press any key to continue once you've made the changes...
    Reading updated user-specific global preferences...
    Reading updated system-wide global preferences...
    Reading updated user-specific system preferences...
    Reading updated system-wide system preferences...
    Reading updated defaults for all domains...
    Capturing updated network settings...
    Comparing preferences and generating diffs...
    Comparing global and system preferences...
    --- /tmp/before_defaults/user_system_defaults.plist	2024-09-30 21:23:17.183140919 -0400
    +++ /tmp/after_defaults/user_system_defaults.plist	2024-09-30 21:23:45.721177080 -0400
    @@ -95,9 +95,9 @@
         };
         ContextStoreAgent =     {
             "_DKThrottledActivityLast_DKKnowledgeStorageLogging_DKKnowledgeStorageDidInsertEventsNotification:/app/mediaUsageActivityDate" = "2024-08-15 01:49:34 +0000";
    -        "_DKThrottledActivityLast_DKKnowledgeStorageLogging_DKKnowledgeStorageDidInsertEventsNotification:/app/usageActivityDate" = "2024-10-01 01:22:53 +0000";
    +        "_DKThrottledActivityLast_DKKnowledgeStorageLogging_DKKnowledgeStorageDidInsertEventsNotification:/app/usageActivityDate" = "2024-10-01 01:23:42 +0000";
             "_DKThrottledActivityLast_DKKnowledgeStorageLogging_DKKnowledgeStorageDidInsertLocalEventsNotification:/app/mediaUsageActivityDate" = "2024-08-15 01:49:34 +0000";
    -        "_DKThrottledActivityLast_DKKnowledgeStorageLogging_DKKnowledgeStorageDidInsertLocalEventsNotification:/app/usageActivityDate" = "2024-10-01 01:22:53 +0000";
    +        "_DKThrottledActivityLast_DKKnowledgeStorageLogging_DKKnowledgeStorageDidInsertLocalEventsNotification:/app/usageActivityDate" = "2024-10-01 01:23:42 +0000";
         };
         LighthouseBitacoraFramework =     {
             "lastAggregationDate_MLHost" = "2024-08-31 00:00:00 +0000";
    @@ -6998,6 +6998,7 @@
             );
         };
         "com.apple.dock" =     {
    +        autohide = 1;
             "last-analytics-stamp" =         (
                 "748840077.891269"
             );
    @@ -12104,7 +12105,7 @@
                 "com.apple.photolibraryd.curatedlibraryprocessing" = "2024-09-30 11:58:18 +0000";
                 "com.apple.photolibraryd.periodicmaintenance" = "2024-09-29 18:28:19 +0000";
                 "com.apple.proactive.PersonalIntelligence.PersonalIntelligenceMetrics" = "2024-09-29 14:29:35 +0000";
    -            "com.apple.proactive.PersonalizationPortrait.ClientLinkStatus" = "2024-09-22 01:54:07 +0000";
    +            "com.apple.proactive.PersonalizationPortrait.ClientLinkStatus" = "2024-10-04 09:16:11 +0000";
                 "com.apple.proactive.PersonalizationPortrait.ContactHandlesCache" = "2024-09-29 23:56:51 +0000";
                 "com.apple.proactive.PersonalizationPortrait.ContactsImport" = "2024-09-29 23:57:21 +0000";
                 "com.apple.proactive.PersonalizationPortrait.CoreRoutineImport" = "2024-09-29 23:56:50 +0000";
    @@ -12115,11 +12116,11 @@
                 "com.apple.proactive.PersonalizationPortrait.ExpiredLinkReview" = "2024-09-29 23:57:21 +0000";
                 "com.apple.proactive.PersonalizationPortrait.FeedbackProcessing" = "2024-09-29 23:56:50 +0000";
                 "com.apple.proactive.PersonalizationPortrait.FeedbackStreamReviewed" = "2024-09-29 23:56:51 +0000";
    -            "com.apple.proactive.PersonalizationPortrait.LinkStatusGeneration" = "2024-09-22 01:54:07 +0000";
    +            "com.apple.proactive.PersonalizationPortrait.LinkStatusGeneration" = "2024-10-04 09:16:11 +0000";
                 "com.apple.proactive.PersonalizationPortrait.LogLocationPerplexity" = "2024-09-29 23:54:27 +0000";
    -            "com.apple.proactive.PersonalizationPortrait.LogNamedEntityFirstSource" = "2024-09-22 01:54:07 +0000";
    +            "com.apple.proactive.PersonalizationPortrait.LogNamedEntityFirstSource" = "2024-10-04 09:16:11 +0000";
                 "com.apple.proactive.PersonalizationPortrait.LogNamedEntityPerplexity" = "2024-09-29 23:56:52 +0000";
    -            "com.apple.proactive.PersonalizationPortrait.LogTopicFirstSource" = "2024-09-22 01:54:07 +0000";
    +            "com.apple.proactive.PersonalizationPortrait.LogTopicFirstSource" = "2024-10-04 09:16:11 +0000";
                 "com.apple.proactive.PersonalizationPortrait.LogTopicPerplexity" = "2024-09-29 23:57:22 +0000";
                 "com.apple.proactive.PersonalizationPortrait.MapsImport" = "2024-09-29 23:57:22 +0000";
                 "com.apple.proactive.PersonalizationPortrait.NamedEntityFiltering" = "2024-09-29 23:57:22 +0000";
    @@ -12136,7 +12137,7 @@
                 "com.apple.proactive.PersonalizationPortrait.TopicImport" = "2024-09-26 17:42:30 +0000";
                 "com.apple.proactive.PersonalizationPortrait.TopicRepairAndExport" = "2024-09-26 17:45:06 +0000";
                 "com.apple.proactive.PersonalizationPortrait.UnsupportedClient" = "2024-09-29 23:57:21 +0000";
    -            "com.apple.proactive.PersonalizationPortrait.VacuumDatabase" = "2024-09-22 01:54:07 +0000";
    +            "com.apple.proactive.PersonalizationPortrait.VacuumDatabase" = "2024-10-04 09:16:11 +0000";
                 "com.apple.proactive.ProactiveHarvesting.Cleanup" = "2024-09-29 14:29:35 +0000";
                 "com.apple.proactive.ProactiveHarvesting.Harvest.PeriodicBackground" = "2024-09-29 21:54:28 +0000";
                 "com.apple.proactived.contextualactions.training" = "2024-09-28 03:57:02 +0000";
    --- /tmp/before_defaults/system_system_defaults.plist	2024-09-30 21:23:17.281165387 -0400
    +++ /tmp/after_defaults/system_system_defaults.plist	2024-09-30 21:23:45.810771555 -0400
    @@ -374,7 +374,7 @@
                 "501:com.apple.mlhost.telemetry.daily" = "2024-09-26 21:59:29 +0000";
                 "501:com.apple.mlhostd.daily" = "2024-09-28 08:35:02 +0000";
                 "501:com.apple.parsec.SafariBrowsingAssistant" = "2024-09-27 02:53:00 +0000";
    -            "501:com.apple.photoanalysisd.backgroundanalysis" = "2024-09-30 20:14:26 +0000";
    +            "501:com.apple.photoanalysisd.backgroundanalysis" = "2024-10-01 00:02:14 +0000";
                 "501:com.apple.photoanalysisd.graphNonIntensiveTasks" = "2024-09-30 20:20:03 +0000";
                 "501:com.apple.photoanalysisd.internal" = "2024-09-15 01:53:51 +0000";
                 "501:com.apple.photoanalysisd.music" = "2024-09-30 17:05:59 +0000";
    @@ -2312,7 +2312,7 @@
             LastOSLaunchVersion = 24A335;
             "baseDate.LocalBeaconingManager" = "2023-06-01 15:07:33 +0000";
             lastAttemptDate = "2024-08-15 01:48:08 +0000";
    -        lastFinderAttemptDate = "2024-10-01 01:23:05 +0000";
    +        lastFinderAttemptDate = "2024-10-01 01:23:36 +0000";
             lastFinderPublishDates =         {
                 batteryWiFi =             (
                     "2024-09-21 01:07:39 +0000",
    @@ -3859,7 +3859,7 @@
                 "com.apple.awdd.publication" = "2024-09-29 18:17:55 +0000";
                 "com.apple.awdd.trigger:0x7f004:86400:2" = "2024-09-28 13:31:28 +0000";
                 "com.apple.awdd.trigger:0x7f006:14400:2" = "2024-09-30 05:24:18 +0000";
    -            "com.apple.backupd-auto" = "2024-10-01 01:08:37 +0000";
    +            "com.apple.backupd-auto" = "2024-10-01 01:38:37 +0000";
                 "com.apple.backupd-auto.dryspell" = "2024-09-28 01:22:46 +0000";
                 "com.apple.backupd.analytics" = "2024-09-28 05:36:06 +0000";
                 "com.apple.biome.prune-expired-events" = "2024-09-28 03:56:23 +0000";
    Comparing Domain Specific
    Comparison complete.Code language: PHP (php)

    You can see that there’s a lot of background noise, but in there is what I was looking for: com.apple.dock and autohide = 1.

    Now I can head over to macos-defaults.com and I can search for com.apple.doc and find the command to set the dock to auto hide.

    defaults write com.apple.dock "autohide" -bool "true" && killall Dock

    Thinking about it, this was probably a dumb example as it was easy to just go to macos-defaults.com and search for “autohide” to find it.

    Well, any way do what you want with this stupid thing.

  • Quick Tip: Script Debugging in WordPress

    Quick Tip: Script Debugging in WordPress

    If you’re debugging core WordPress scripts, one thing you might run into is dealing with cached copies of the script. Due to how script-loader.php enqueues the core files, their versions are “hard coded” and short of editing script-loader.php as well, there’s a way to fix this via a filter:

    add_filter( 'script_loader_src', function( $src, $handle ) {
         if ( false !== strpos( $src, 'ver=' ) ) {
             $src = remove_query_arg( 'ver', $src );
             $src = add_query_arg( array( 'ver', rawurlencode( uniqid( $handle ) . '-' ) ), $src );
         }
         
         <span style="background-color: inherit; color: rgb(248, 248, 242); font-size: inherit; letter-spacing: -0.015em;">return $src;</span>
     }, -1, 2 );Code language: PHP (php)

    This will apply a unique ver argument to the core scripts on each refresh, so no matter what you’re editing you should get the most recent version from both any page cache you may have and also the browser cache (🤞).

    Also, don’t forget to enable SCRIPT_DEBUG if you’re hacking away at core scripts to debug issues.

    I couldn’t find a good related image, so enjoy this delicious toilet paper.

  • Quick Tip: DreamHost cron and WP-CLI

    Quick Tip: DreamHost cron and WP-CLI

    If you’re hosting your WordPress website on DreamHost, and use their cron system to offload your WordPress faux-cron for better reliability, be careful of what version of PHP you have in your code.

    I recently had an issue where my cron events weren’t firing, and after enabling email output, I ended up with something like this PHP error message:

    Parse error: syntax error, unexpected '?' in /path/to/file.php on line 123

    It turns out that WP-CLI was running PHP 5.x via the DreamHost cron system.  I had PHP 7.x specific code in my theme.
    To fix this, I had to set the WP_CLI_PHP environment variable in my cron job:

    export WP_CLI_PHP=/usr/local/php72/bin/php
    wp cron event run --due-now --path=/home/path/to/wp/ --url=https://example.com/Code language: JavaScript (javascript)