I have a data gathering app (terrestrial magnetic field strength) that has four phases; they run, via cron, at 2,3,4, and 5 minute intervals, ordered so that everything needed for one step is collected before it happens.
Because of the intervals, I can’t, as I understand it, use launchd to fire the phases; consequently, I use cron. And I want to use cron; I like it, it’s convenient, familiar, etc.
But cron, under 10.5.8 Leopard (required — driver issues preclude 10.6), vomits the subject message with every launch, basically littering what would be a useful window with useless trash. In the crontab, I’m setting the PATH, SHELL and HOME variables; the apps, which are written in python, all run properly and with the expected R/W access to the equipment, directories and files they need to get at; they launch other python subtasks fine; yet, there’s the complaint from cron at launch, as if something is wrong.
Perhaps something is. But googling, I basically found four things:
1) This problem has existed for a loooong time — Apple has not addressed it
2) If something’s actually wrong with a typical cron launch, no one seems to know what it is
3) This is really common, and the usual suggestion is “launchd”, which won’t work
4) The only suggestion even close to a solution is to set /etc/syslog.conf logging level for the console to err instead of notice; but then one loses many benefits of the console in that case, and I’m very reluctant to run that way.
What I”m hoping is that here on stackoverflow, there will be someone who actually knows specifically what the error message means (as opposed to “launchd is unhappy / busted”) or has even quietly solved the problem on their own.
Also, if I figure this out — I’ve spent an unconscionable number of hours on it already — I’ll post here and so others can finally find a solution.
Ok. I’ve done a LOT of googling, and there are several things of note about this issue. First, the problem has existed for years. There are huge numbers of complaints about it on the net. I found a post in the Apple dev forums where it was said that Apple knew about it, it’s a bug, and would be fixed at some future point. Of course, that remark was posted years ago (three, in fact), and apparently, Apple isn’t going to fix it. And in the meantime, I have these bloody console messages which are seriously inconveniencing me. I have real work to do and I need to use the console output in that work.
So I fixed it. 🙂 Yes, my cron jobs are now running quietly and correctly, the way they always should have.
Now, I would like to emphasize that this is a brutal fix, and a hack, but it is fairly specific to the problem, I don’t think it can hurt anything else (if performed correctly), and serves MY needs perfectly. Your mileage may differ, and if you’re not a technical person, stop reading now and just forget your ever saw this post. Really. Stop now.
So basically, as you can see in the above posting of the relevant chunk of source code from launchd that Graham dug up, there’s a function call that reports this particular error. And pretty much just this particular error.
It has four parameters, one of which is returned from a call to mach_error_string(). The only parameter that is a pointer (meaning, the called routine could somehow get back to the original parameter) is the string pointer, and self-modification of a static format string… nah. That’s not the kind of thing serious Koolaid drinkers would ever do. So the call isn’t doing anything to those parameters; its just using them to report the error. So clearly, we don’t need to make this call. Ah-ha. 🙂
This call to mach_error_string turns out to be a unique signature in the 10.5.8 version of launchd. That allowed me to precisely locate the code within the launchd executable. Once there, it was pretty obvious (to me, anyway) what is going on; there are the appropriate number of move instructions, then the call, then the loop is checked and either exited or re-run. Here’s the relevant portion of the disassembly:
The binary signature of the call (again, I emphasize, in the 10.5.8 version of launchd on my machine) is: E857AFFFFF. There’s only one instance of this binary string in the entire file.
What we need to do here is replace that with something harmless (in context) of the same length. nearby, there’s an immediate AND instruction for eax; that’ll do. The value in eax isn’t used again as the loop ends after the call. The binary for that AND instruction is: 25FF030000. Even if, worst case, at load time, the code were relinked so that (what was) the calll address was changed, all that would happen is the and instruction would have a different AND pattern. So no matter what, this should be ok to do.
So we replace the E857AFFFFF with 25FF030000, and now what the code does is load up those parameters, AND the eax register to no point at all, and go on with life. no more “Could not setup Mach task special port %u: %s” messages. Ever. And launchd will continue to work just like it always did, because all that has been done here is to excise a call to log an error message.
Now… just a couple closing remarks.
First, although the hack is quite specific, it isn’t what I’d call surgically precise; it is possible that there might be lurking somewhere a situation that would legitimately call for this message, or a message emitted using this format string and parameters with a different port number and/or string at the end; and that’s not going to be logged if it happens. So be aware of that. Error handling, such as it is, won’t change, but the logging… that’s now impossible.
Second, this is hacking in the classic sense; for me, it was both fun and very satisfying, serving the purpose of raising my central digit in Apple’s general direction for inconveniencing me with something they could have easily fixed themselves; for you, though, if you’re not comfortable with machine code and binary, and/or not very certain you can do this exactly right… and you’re not completely prepared to have to firewire into your machine and replace the hacked launchd with the original again… or you don’t have 10.5.8… don’t even try it. Just write Apple and tell ’em to fix their broken launchd.
So… Apple gives us a bug; drops the ball on fixing it; I entirely lost patience and hacked it out of my face. And there you have it. Pbbffft.