Wandering Thoughts archives

2012-04-21

Bash's superintelligent errors about exec failures

Let's take a closer look at bash's error message from yesterday, because if you pay close attention something really interesting is going on. Here's the error message again:

bash: /tmp/exmpl: /bin/shx: bad interpreter: No such file or directory

On first blush, if you don't think about it too much, this looks perfectly sensible: bash is reporting that when it tried to exec() the /tmp/exmpl, the kernel told it that there was a problem with the script's interpreter.

But, wait. When the exec() fails, all that kernel can tell bash is the errno number. In this case the kernel returns ENOENT, which creates the 'No such file or directory' portion of the error message. So how does bash know that the reason that trying to run /tmp/exmpl failed is because /bin/shx doesn't exist?

Here, have another example error message from bash:

bash: /tmp/a.out: /lib64/ld-ZZZZZ-x86-64.so.2: bad ELF interpreter: No such file or directory

(I did some binary editing to create that failure.)

That's right. When an exec() fails, bash opens the executable and parses it to try to identify what went wrong. It recognizes shell scripts, which is easy, but it also parses ELF binaries to find things like the name of the ELF interpreter, so it can check that. Let me say that again: bash knows how to parse ELF binaries so that it can give you good error messages. I must applaud bash's attempt to be almost as user friendly as possible, but at the same time I think it went more than a little bit overboard.

(If you trace the system calls it's using, you can clearly see it selectively reading several bits of the ELF binary.)

If you try these same things in other, simpler shells, they will simply report something like '/tmp/exmpl: No such file or directory', ie they are simply doing a straightforward translation of what the kernel told them (even if it is a rather puzzling message).

(zsh will report the interpreter problem with a shell script but not with a binary, which strikes me as a reasonable amount for a complex shell to do. Checking for this error with shell scripts is not that difficult and it does happen periodically.)

unix/BashSuperintelligentExec written at 01:16:45; Add Comment


Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.