Where are core dumps written on Mac? - macos

On Mac OS X, if I send SIGQUIT to my C program, it terminates, but there is no core dump file.
Do you have to manually enable core dumps on Mac OS X (how?), or are they written to somewhere else instead of the working directory?

It seems they are suppressed by default. Running
$ ulimit -c unlimited
Will enable core dumps for the current terminal, and it will be placed in /cores as core.PID. When you open a new session, it will be set to the default value again.

On macOS, your crash dumps are automatically handled by Crash Reporter.
You can find backtrace files by executing Console and going to User Diagnostic Reports section (under 'Diagnostic and Usage Information' group) or you can locate them in ~/Library/Logs/DiagnosticReports.
You can also check where dumps are generated by monitoring system.log file, e.g.
tail -f /var/log/system.log | grep crash
The actual core dump files you can find in /cores.
See also:
How to generate core dumps in Mac OS X?
Technical Note TN2118: Kernel Core Dumps.

Additionally, the /cores directory must exist and the user running the program must have write permissions on it.

The answer above,
ulimit -c unlimited
works -- but be sure to run that in the same terminal from which you will run the program that dumps core. You need to run the ulimit command first.

by default, specific directories in mac osx are hidden. you might want to enable this feature in the terminal and then the core dump should be visible within the directory /cores.
defaults write com.apple.finder AppleShowAllFiles TRUE

There is a great explanation by Quinn “The Eskimo!” on Apple's forums
https://developer.apple.com/forums/thread/694233
I roughly followed that guide. Here are the steps that I did.
Grant write all access to the /cores dir
PROMPT> ls -la / | grep cores
drwxr-xr-x 2 root wheel 64 Dec 8 2021 cores
PROMPT> sudo chmod 1777 /cores
PROMPT> ls -la / | grep cores
drwxrwxrwt 2 root wheel 64 Dec 21 23:29 cores
Set size of core file
PROMPT> ulimit -c unlimited
Compile and sign the program
PROMPT> cargo build --release -p my-crashing-program
PROMPT> /usr/libexec/PlistBuddy -c "Add :com.apple.security.get-task-allow bool true" tmp.entitlements
PROMPT> codesign -s - -f --entitlements tmp.entitlements my-crashing-program
Run the program
PROMPT> my-crashing-program
thread 'main' panicked at 'boom', my-crashing-program/src/main.rs:74:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
dumping core for pid 80995
zsh: quit my-crashing-program
Now there is a core file
PROMPT> ls /cores
core.80995
Also Apple's Console app has a list with Crash Reports.

Related

Is there a way to recreate /dev within a directory on macOS for the purpose of chroot-ing?

I've been experimenting with running apps within a chroot-ed directory.
Many apps and binaries require access to items within /dev, such as /dev/null and /dev/random to work.
Is there a way to recreate or bind mount the /dev filesystem within a directory to this end?
I have tried the following without success:
(Where root is the directory I want to chroot into)
$ sudo bindfs -o dev -o allow_other /dev ./root/dev/
Leading to:
$ cat ./root/dev/urandom
cat: ./root/dev/urandom: Operation not permitted
$ mount -t devfs devfs ./root/dev
Leading to:
$ cat ./root/dev/urandom
cat: ./root/dev/urandom: Device not configured
Attempting to manually make the devices with mknod doesn't work either.
$ sudo mknod null c 1 3
$ sudo chmod 666 ./null
$ cat ./null
cat: ./null: Operation not permitted
Is there a way to either use the existing /dev items within a chroot or to recreate them?
Unfortunately, there doesn't appear to be much documentation of using chroot with OSX/macOS on the internet.
Operating System Details: macOS Mojave, 10.14.6. SIP enabled.
Well, this one is mainly on me being dumb.
sudo mount -t devfs devfs ./dev
Works just fine.
If the above command is ran without root, it will bind the devfs devices within ./dev, but all devices will respond with a "Device not configured" error. If it is ran as root, all ./dev devices will work as expected.

List All Loaded/Unloaded or Both Launch Agents On macOS

I am trying to figure out how many launch agents are loaded right now using following command the it
find /System/Library/Launch* /Library/Launch* ~/Library/Launch* -name '*.plist' -exec sh -c '/usr/libexec/PlistBuddy -c "Print Label" {} && echo {}' ';' | grep -wf <(launchctl list | grep -o "\S\+\..*$") -A1
grep -B 1 -A 1 "active count = 1$" <<< "$(launchctl dumpstate)"
but its not listed the one I am looking for.
is it correct?
Using launchctl you can list all the running agents and daemons like such:
launchctl list
and
sudo launchctl list
please note that the two are different commands.
Oddly enough, running sudo launchutil list prints out the root daemons, and only the root deamons.
If you are running the commands in the terminal you will want to run the non-sudo version first, because if you don't, the sudo version will create a root session which will force version #1 to have root privileges anyways!
If you would like to find the file path to such an agent or daemon, this
may help.
Edit:
Okay, I don't know how I missed the word "unloaded" in the giant title in your question but... here are the directories that daemons/agents like to hide in (copied from the man page of launchctl):
FILES
~/Library/LaunchAgents Per-user agents provided by the user.
/Library/LaunchAgents Per-user agents provided by the administrator.
/Library/LaunchDaemons System wide daemons provided by the administrator.
/System/Library/LaunchAgents OS X Per-user agents.
/System/Library/LaunchDaemons OS X System wide daemons.
I had your same question and this article was super helpful. I suggest reading through it, but here's a relevant snippet:
While it’s not a simple matter for users to enumerate all the Login Items, admins can do so with a little extra work by parsing the following file, if it exists: ~/Library/ApplicationSupport/com.apple.backgroundtaskmanagementagent/backgrounditems.btm
Parsing that file is more complicated than opening it with your favorite editor. The article links to a paste bin, but this github repo is a one-stop shop. Still, the article will help a lot.

dtruss fails on ps on OS X 10.11

I was trying to see which syscall ps uses to get the command line of a process on OS X 10.11 (El Capitan), and ran into the following error:
# dtruss ps -p 43520 -o args
dtrace: failed to execute ps: dtrace cannot control executables signed with restricted entitlements
Googling resulted in the suggestion that making a copy of ps would allow me to bypass this, but that didn't work for me. Why can't I run dtruss on arbitrary binaries anymore, and is there any way for me to restore the old behavior?
The issue has to do with the code signature. If you make a copy and then re-sign it with your own identity (or, presumably, any non-Apple identity), then dtrace will attach to it just fine.
$ mkdir ~/temp
$ cp /bin/ps ~/temp/
$ codesign -f -s `whoami` ~/temp/ps
$ sudo dtruss ~/temp/ps -p 43520 -o args
cannot control executables signed with restricted entitlements
Security Integrity Protection ('rootless') is now preventing dtruss from operating here.
You can disable it by booting into Recovery mode, but it looks like dtrace has specifically been blocked regardless of the state of rootless, as can be seen in the source code if you search for "dtrace cannot control".
You can also see from the comments in Pcreate:
/*
* <rdar://problem/13969762>:
* If the process is signed with restricted entitlements, the libdtrace_dyld
* library will not be injected in the process. In this case we kill the
* process and report an error.
*/

Windows 7 Task Scheduler BASH Script Fails

In order to use rsync I created a BASH script. It runs fine from the Cygwin shell in WIN 7 but fails when run from the WIN 7 Task Scheduler. My Task Scheduler Script is a simple:
c:\cygwin\bin\bash.exe -l -c "~user/rsync_Windows_Backup 2>&1 >> ~user/Documents_cron.log"
The initial directory is set to C:\Cygwin\bin.
My BASH script is a typical rsync command with [options] SRC DEST and some related housekeeping.
The rsync command within the "rsync_Windows_Backup" BASH script is:
/bin/time -f "\nElapse (hh:mm:ss.ss) %E" \
rsync.exe -v -rltz --chmod=a=rw,Da+x -u "$SRC" "$DEST" >> "$LOG" \
2 >> "$LOG"
$ ./rsync_Windows_Backup - succeeds.
But the Task Scheduler Job fails carping that it cannot find the DEST Folder that the BASH script references. When I do a "cd DEST" from the BASH command line the Folder is avialable and can be written to.
I should add some more details that the sender is a WIN 7 desktop that is mapped to a Vista desktop receiver with a drive mapping J:. The BASH script does start but fails with:
rsync: writefd_unbuffered failed to write 4 bytes to socket [sender]: Broken pipe (32)
rsync: mkdir "/cygdrive/J/DocumentsBackup" failed: No such file or directory (2) rsync error: error in file IO (code 11)
I have tried several ideas to influence how WIN 7 handles mappings and permissions assuming this is the root of the problem. So far nothing seems to help.
Another characteristic is that the exact same BASH script and Task Scheduler Job does succeed it WIN Vista Business Edition. So I am assuming there is something in WIN 7 that I am missing.
I am stumped and could use some guidance.
Thanks.
I now have this working in Win 7 from the task scheduler as I need. Thank you to #netubsi and #firerat of LinuxQuestionsorg and #konsolebox for the suggestions that lead to a solution.
Here is what I did:
cmd /c net use T: '\\server\share' # Created a separate temporary share for Cygwin
DEST="/cygdrive/T/User/FolderBackup/" # Use temporary Share in Destination
rsync -avuz --copy-links "$SRC" "$DEST" # Do backup
cmd /c net use T: /delete # Remove temporary share
It appears that in WIN 7 the share created in Windows is NOT available to a Cygwin script, IF it is launced from the Win 7 task scheduler. It IS available if the script is launced from the Cygwin command line. It also appears that this is NOT an issue in Win Vista.
This seems odd to me. Perhaps there is another explanation that I am missing. However I am just relieved to have this working!!
You can also just use the network address directly in cygwin:
DEST="//server/share/User/FolderBackup"
Cygwin mounts local and mapped drives under /cygdrive. Using taskscheduler in win7 if you list the contents of /cygdrive, all you will see are local drives???
First option is to run your script as
c:\cygwin\bin\bash.exe -l -c "~/rsync_Windows_Backup >> ~/Documents_cron.log 2>&1"
If you want to capture the stderr output as well, you have to place it in front to copy the fd of the file, and not of stdout.
Make sure that rsync_Windows_Backup has executable permissions. Running ls -l ~/rsync_Windows_Backup should show it.
If it doesn't work, try to use absolute paths. On your Cygwin screen where the current direcory shows ~ in the prompt type pwd which would show something like
User#System ~
$ pwd
/home/User
Basing from that as an example your command should now be like:
c:\cygwin\bin\bash.exe -l -c "/home/User/rsync_Windows_Backup >> /home/User/Documents_cron.log 2>&1"

How to enable full coredumps on OS X?

It looks that OS X (10.6) does not generates codedumps by default.
Using the ulimit -c unlimited is not a good solution because ulimit does set the limit in an environment variable. This will work only for console applications executed from the shell that executed ulimit. If you have a gui application this will not work.
You can enable core dumps and then launch your GUI app from the command line using open.
$ ulimit -c unlimited
$ open /Applications/Address\ Book.app
I just looked at TN2124 and it suggests a similar approach, only without using open and just launching the app directly, e.g.
$ ulimit -c unlimited
$ /Applications/TextEdit.app/Contents/MacOS/TextEdit

Resources