11

I'm having some problems with a program causing a segmentation fault when run on a Mac. I'm putting together an entry for the IOCCC, which means the following things are true about my program:

  • It's a very small C program in a single file called prog.c
  • I won't post it here, because it won't help (and would probably render the contest entry invalid)
  • It compiles cleanly under gcc using "cc -o prog prog.c -Wall"
  • Despite (or, more accurately, because of) the fact it contains a bunch of really bizarre uses of C, it has been constructed extremely carefully. I don't know of any part of it which is careless with memory (which is not to say that there can't possibly be bugs, just that if there are they're not likely to be obvious ones)
  • I'm primarily a Windows user, but several years ago I successfully compiled and ran it on several windows machines, a couple of Macs and a Linux box, with no problems. The code hasn't changed since then, but I no longer have access to those machines.

I don't have a Linux machine to re-test on, but as one final test, I tried compiling and running it on a MacBook Pro - Mac OSX 10.6.7, Xcode 4.2 (i.e. GCC 4.2.1). Again, it compiles cleanly from the command line. It seems that on a Mac typing "prog" won't make the compiled program run, but "open prog" seems to. Nothing happens for about 10 seconds (my program takes about a minute to run when it's successful), but then it just says "Segmentation fault", and ends.

Here is what I've tried, to track down the problem, using answers mostly gleaned from this useful StackOverflow thread:

  • On Windows, peppered the code with _ASSERTE(_CrtCheckMemory()); - The code ran dog-slow, but ran successfully. None of the asserts fired (they do when I deliberately add horrible code to ensure that _CrtCheckMemory and _ASSERTE are working as expected, but not otherwise)
  • On the Mac, I tried Mudflap. I tried to build the code using variations of "g++ -fmudflap -fstack-protector-all -lmudflap -Wall -o prog prog.c", which just produces the error "cc1plus: error: mf-runtime.h: No such file or directory". Googling the matter didn't bring up anything conclusive, but there does seem to be a feeling that Mudflap just doesn't work on Macs.
  • Also on the Mac, I tried Valgrind. I installed and built it, and built my code using "cc -o prog -g -O0 prog.c". Running Valgrind with the command "valgrind --leak-check=yes prog" produces the error "valgrind: prog: command not found". Remembering you have you "open" an exectable on a Mac I tried "valgrind --leak-check=yes open prog", which appears to run the program, and also runs Valgrind, which finds no problems. However, Valgrind is failing to find problems for me even when I run it with programs which are designed specifically to make it trigger error messages. I this also broken on Macs?
  • I tried running the program in Xcode, with all the Diagnostics checkboxes ticked in the Product->Edit Scheme... menu, and with a symbolic breakpoint set in malloc_error_break. The breakpoint doesn't get hit, the code stops with a callstack containing one thing ("dlopen"), and the only thing of note that shows up in the output window is the following:

Warning: Unable to restore previously selected frame. No memory available to program now: unsafe to call malloc

I'm out of ideas. I'm trying to get Cygwin set up (it's taking hours though) to see if any of the tools will work that way, but if that fails then I'm at a loss. Surely there must be SOME tools which are capable of tracking down the causes of Segmentation faults on a Mac?

Community
  • 1
  • 1
electrodruid
  • 1,083
  • 2
  • 9
  • 13
  • 3
    As with any UNIX, unless `prog` is in your `PATH`, you will need to specify the path to `prog` to run it, e.g. `./prog` from within the directory it lives. It's the same story with the valgrind invocation above; it should probably be `valgrind --leak-check=yes ./prog`. Do not use `open` to run your code. – James Dec 03 '11 at 20:52
  • As for not having access to a Linux machine ... seriously? Just download a Live CD image of Ubuntu, put it on a CD/USB drive, and boot into ... OMG Ponies! It's like totally *Linux*. (Sorry for being a bit snarky, but figuring out this solution does *not* require that you be a Rocket Surgeon.) – Peter Rowell Dec 04 '11 at 19:06
  • So uh .. did you win ? :-) ... if so what entry? (I'm a three time winner btw.) – Pryftan Mar 24 '23 at 12:36
  • I did not win :( I was very proud of my entry, but sadly it didn't show up when the winning entries were announced. I had another couple of attempts in later years, but I had already pushed myself about as far as I think I was capable of in this entry. Congratulations on your wins, though! – electrodruid Mar 25 '23 at 22:32

3 Answers3

12

For the more modern lldb flavor

$ lldb --file /path/to/program
...
(lldb) r
Process 89510 launched
...
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x726f00)
  * frame #0: 0x00007fff73856e52 libsystem_platform.dylib`_platform_strlen + 18
...
Roy Shilkrot
  • 3,079
  • 29
  • 25
10

Have you compiled with -g and run it inside gdb? Once the app crashes, you can get a backtrace with bt that should show you where the crash occurs

Brendan Shanks
  • 3,141
  • 14
  • 13
  • 2
    Perfect! I hadn't used gdb before, but it hit the problem right away and made the problem clear in a way that XCode utterly and miserably failed to do. If anyone is interested, my problem seemed to come down to the way the Macbook Pro handled floating-point arithmetic. My code contains a recursive function which stops recursing when it's found the correct answer to within a small defined tolerance, but on the Macbook it never quite seemed to get close enough, so it recursed forever and blew the callstack (hehe, Stack Overflow...). Increasing the tolerance fixed everything. – electrodruid Dec 04 '11 at 19:46
  • 2
    Insert reference to here. – Randy Howard Apr 20 '13 at 06:38
  • 2
    Note that on newer OS/Xcode versions, you use `lldb` instead. It works the same way, though. – SilverWolf Nov 24 '17 at 21:48
  • Made my day after a decade (Sept 2021). Thanks. – Pavithran Ravichandiran Sep 19 '21 at 03:30
4

In many cases, macOS stores the recent program crash logs under ~/Library/Logs/DiagnosticReports/ folder.

Usually I will try the following steps when doing troubleshooting on macOS:

  1. Clean the existing crash logs under the ~/Library/Logs/DiagnosticReports/
  2. Run the program again to reproduce the issue
  3. Wait for a few seconds, the crash log will appear under the folder. The crash log is named like {your_program}_{crashing_date}_{id}_{your_host}.crash
  4. Open the crash log with your text editor, search for the keyword Crashed to locate the thread causing the crash. It will show you the stack trace during crash, and in many cases, the exact line of source code causing the crash will be recorded as well.

Some links:

[1] https://mac-optimization.bestreviews.net/analyze-mac-crash-reports/

nybon
  • 8,894
  • 9
  • 59
  • 67