Showing posts with label macOS. Show all posts
Showing posts with label macOS. Show all posts

Wednesday, March 4, 2026

How I fixed Sequoia's screencapture on an OCLP patched MacBookPro8,1

Problem

On an early 2011 MacBook Pro (Model MacBookPro8,1), I upgraded from Catalina 10.15.8 to Sequoia 15.7.1 using OCLP 2.4.1. Following the upgrade, the screen capture features stopped working. While I could still trigger the shortcuts (Cmd+Shift+3 for the whole screen or Cmd+Shift+4 for a selected area), the screenshot images no longer appeared on the desktop as expected.

Investigation

Previously, I successfully upgraded several MacBookPro9,2 models (the Mid-2012 version with user-replaceable RAM and SSD) from Catalina to Sequoia 15.7.4 using OCLP 2.4.1 without any issues. This suggested a specific compatibility problem with the older 8,1 model.

Upon further investigation, I discovered that the screencapture binary crashes immediately on the MacBookPro8,1. Running it via the command line yielded:

% /usr/sbin/screencapture
zsh: killed     /usr/sbin/screencapture  

In contrast, the MacBookPro9,2 handles the command normally:

% /usr/sbin/screencapture
screencapture: no file specified  

Beyond just a difference in file size, using the file command revealed a discrepancy in architectures. On the older model, the binary only contains code for x86_64, whereas the binary on the later model is a Universal binary containing both x86_64 and arm64e. It appears the binary on the 8,1 model may have been stripped or corrupted during the patching process.

The Workaround

Regardless of the root cause, I found that copying the functional binary from the newer model to the older one restores functionality.

However, this isn't as simple as a standard file copy. The /usr/sbin directory is protected by System Integrity Protection (SIP) and the partition is mounted as read-only. Furthermore, reapplying OCLP root patches in the future would likely overwrite the fix.

To solve this, I wrote a shell script to automate the process, making it easy to re-apply the fix whenever necessary without manual re-mounting or complex commands. 

The script is now available here: https://github.com/jonelo/screencapture-fix

Precondition: SIP must be disabled. The script expects an unmodified screencapture binary in the same directory where the script is stored. To restore your screen capture functionality, simply run:

% sudo ./screencapture-fix.sh


Sunday, October 13, 2019

AHT Fix - restore the Apple Hardware Test on your (old) Mac

This article applies to you only if you have an old Mac that was released before June 2013. Yes, this article is about old hardware that is still out there. It is even still traded on ebay for exmaple. So I am pleased to announce AHT Fix. The tiny app restores the Apple Hardware Test on older Macs (released before June 2013) where Mac OS X, OS X or macOS has been reinstalled from scratch. Please also have a look at the "Implementation details and credits" in this article.

The Problem

„Apple Hardware Test (AHT) contains a suite of diagnostics that will test the hardware of your computer. […] If your Mac was released after June 2013, you will use Apple Diagnostics rather than Apple Hardware Test (AHT).“ See also https://support.apple.com/en-us/HT201257

If you have reinstalled an older Mac from scratch, the diagnostic tools might no longer be available. If there is content in /System/Library/CoreServices/.diagnostics you are affected. Unless you have the original disks that came with your Mac, there seems to be no way to restore the AHT.

The Solution

AHT Fix. You can grab a copy from https://github.com/jonelo/ahtfix

The application will determine the model of your Mac, query an Apple server, download the appropriate AHT binaries and restore it on your Mac. And once restored you just need to follow the instructions at https://support.apple.com/en-us/HT201257 in order to perform all hardware diagnostics on your Mac.

Note: Starting with El Capitan (OS X 10.11) there is a new feature called System Integrity Protection (SIP) that prevents the modificaiton of a number of operating sytem directories by default.
In order to use AHTFix on El Capitan and later you have to disable SIP temporarily.
See also https://www.macworld.com/article/2986118/security/how-to-modify-system-integrity-protection-in-el-capitan.html

System Requirements

  • A Mac, released before June 2013
  • Mac OS X 10.6 or later
  • SIP disabled if you run El Capitan (OS X 10.11) or later
  • An internet connection (any bandwidth)

Implementation details and credits

On https://github.com/upekkha/AppleHardwareTest you find detailed instructions from Claude Becker how to restore the AHT manually. I put those instructions (and a few more) to a bash script so that you can restore the AHT in a comfortable way.

I also would like to thank Apple for hosting the AHT binaries on their servers. That really helps users to restore the AHT on Macs that would be otherwise incomplete.



Sunday, October 22, 2017

How to open your browser from bash on Windows (WSL), GNU/Linux, macOS and Solaris

Sometimes it can be useful to open a browser from your bash. I have developed a bash function that does exactly that - and since I am a fan of multiple operating systems - the function works not only on GNU/Linux, macOS, and Solaris but also on the bash on Windows as part of the WSL (Windows Subsystem for Linux).


function openBrowser() {
  URL=$1
  OS=$(uname -s)
  case "$OS" in
      Darwin)
          open "$URL"
          ;;
      Linux)
          if [[ "$(cat /proc/sys/kernel/osrelease)" =~ "Microsoft" ]]; then
              # We are in bash on WSL (Windows Subsystem for Linux)
              # We don't need a Linux-Browser and an X-Server,
              # we just can call iexplore.exe,
              # see also https://msdn.microsoft.com/en-us/commandline/wsl/interop
              if [[ "(uname -p)" == "x86_64" ]]; then
                  /mnt/c/Program\ Files/Internet\ Explorer/iexplore.exe "$URL" 2> /dev/null
              else
                  /mnt/c/Program\ Files\ \(x86\)/Internet\ Explorer/iexplore.exe "$URL" 2> /dev/null
              fi
          else
              xdg-open "$URL"
          fi
          ;;
      Solaris)
          /usr/dt/bin/sdtwebclient "$URL"
          ;;
      *)
          printf "Not supported on %s\n" "$OS"
          ;;
  esac
}

To use the function in your bash-script, simply source the file that contains the function - I called the file network.include. You find the file as well at the repository of my tiny project called bashberries - that is a tiny collection of both bash scripts and bash includes, released under the terms of the Apache 2.0 license. The script below calls the function from above and opens the homepage to bashberries:


#!/usr/bin/env bash
. ./network.include
openBrowser https://github.com/jonelo/bash-dwarfs

Best regards,
Johann

Update Oct 23, 2017:
uname -r is not reliable enough, it does not work on the wls beta with Ubuntu 14.04 for example, better is to do a cat /proc/sys/kernel/osrelease

Update Oct 23, 2017:
bash-dwarfs has been renamed to bashberries.

Friday, June 9, 2017

macOS: To use the java command-line tool you need to install a JDK - are you kidding me?

Recently I detected an error message on macOS saying that it seems to be required to install a JDK in order to just use the java command-line tool. A JRE is not enough? Really? Are you kidding me?

The screenshot below shows the error message in German: "Um das java-Befehlszeilenprogramm nutzen zu können, musst du ein Java-Entwicklerpaket installieren." In English it means: "To use the java command-line tool you need to install a JDK".


Since I am a developer, I always installed the JDK on my Mac and I detected that phenomenon very late. Actually the web is full of those traces - however, without a suitable solution in my opinion. Well, I simply don't want to tell my users to install a JDK if a simple JRE is enough. Any existing JRE on the system should do the job in my humble opinion.

Here we go, here is my little bash launcher that tries its best to launch java even if you have installed a JRE only on your Mac:
#!/bin/bash
if [[ ! -z $JAVA_HOME ]]; then
    JEXEC=$JAVA_HOME/bin/java
else
    LIBEXEC=$(/usr/libexec/java_home 2> /dev/null | head -1)
    # is there a JDK?
    if [[ ! -z $LIBEXEC ]]; then
        JEXEC="$LIBEXEC/bin/java"
    else
       # is there a JRE?
       JRE=/Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java
       if [[ -f "$JRE" ]]; then
           JEXEC="$JRE"
       else
           JEXEC=java
       fi
    fi
fi
"$JEXEC" "$@"

The script checks for the JAVA_HOME environment variable and if that is not set, it checks for any registered JDKs by calling /usr/libexec/java_home and if that didn't return anything, it simply uses the JRE that could be available at a well known path on macOS (tested with both Java 8u131 and Java 9-ea) and if that fails as well, it uses java and if even that fails it means you really don't have any Java installed and you should get the error message above again.

I use the launcher above already as part of the Jacksum macOS Finder integration. See also
http://jacksum.net/de/tutorials/integration_jacksum_osx_finder.html

Feel free to use the launcher script for your Java app as well if it meets your needs.


Sunday, May 28, 2017

Solaris' pargs, penv, pfiles, pmap, pstack, and pwdx on macOS

Three weeks ago I posted Solaris' pargs, penv, pfiles, pmap, and pstack on GNU/Linux and since I am also a Mac user, I thought it could be a good idea to have those commands also on macOS. Here we go ...

function pargs()  { L=$(ps ww $1 | tail -1); echo ${L:27}; }
function penv()   { L=$(pargs $1); C=${#L}; L=$(ps wwe $1 | tail -1); L=${L:27}; echo ${L:$C} | tr ' ' '\n'; }
function pfiles() { lsof -p $1; }
function pmap()   { vmmap $1; }
function pstack() { echo "thread backtrace all" | lldb -p $1; }
function pwdx()   { L=$(lsof -a  -d cwd -p $1 | tail -1); echo /${L#*/}; }

Since there is no access to a proc file system on macOS (at least not by default), both pargs and penv call the ps command and pmap calls vmmap. Furthermore pwdx calls lsof with the current working directory descriptor request in order to get the required info. Since "ps wwe" returns not only the environment variables for the given process but also the program arguments on macOS, we need to strip the program arguments from the output. This has been done by calling pargs, determining the length of that output and cutting that length from the string again before we pass it to the tr command that gives us an environment variable for each line. For blog purposes I have shortened the variable names, L stands for line and C for count.

References:
http://wiki.bash-hackers.org/syntax/pe
http://yongsun.me/2009/01/tips-the-equivalents-of-ldd1-and-pmap1-on-mac-os-x/