Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can anyone explain what IOT instruction (core dumped) refers to?

I’m getting the following problem when executing a C program:

~$ ./a.out
zsh IOT instruction (core dumped) ./a.out

I’ve never seen this before, and I don’t know how to solve it. What is it?

Please not that I’m not looking for a solve to this problem, but to understand what the problem is, so I can fix it. Google has yielded nothing that helps.

like image 329
R-Rothrock Avatar asked Dec 05 '25 08:12

R-Rothrock


1 Answers

tl;dr: It means that abort() was called. And now, you have to figure out why it was called. (The core dump might help.)

But, why the strange message? I decided to look into it.

Once upon a time, there was a computer called the PDP-11. It had an instruction named IOT, "I/O Trap" which would cause a certain type of trap to the operating system. It seems that Unix on the PDP/11 would handle this trap by delivering a specific signal to the process, whose numeric value was assigned to the macro SIGIOT in <signal.h>.

The macro is still supported by modern Linux, probably so that old programs that hardcode a list of signal macros would still compile. However, it's assigned to the same number (6) as the more common SIGABRT, which is the signal raised when abort() is called. So in effect, SIGIOT is merely a legacy alias for SIGABRT.

But the message? We're getting to that. Keep in mind that the macro names SIGIOT and SIGABRT only exist at compile time; at runtime, all a process would see is the integer value 6. To translate it to something human-readable, the usual way is to call the standard library strsignal function. On Linux with glibc, strsignal(6) returns the string Aborted which is quite reasonable. This is what most shells would use to report the signal that killed your process.

But zsh, for some reason, wants to be different. They don't use the standard strsignal function, but rather they roll their own. They have a pair of scripts (signame1.awk signame2.awk) that parse the system's signal.h file to see what signals exist, then generate a lookup table to map the numeric values to predefined strings. The awk code looks like:

    if (signam == "ABRT")   { msg[signum] = "abort" }
    if (signam == "ALRM")   { msg[signum] = "alarm" }
    # ...
    if (signam == "IO")     { msg[signum] = "i/o ready" }
    if (signam == "IOT")    { msg[signum] = "IOT instruction" }
    if (signam == "KILL")   { msg[signum] = "killed" }
    # ...

And now you see the issue. Since SIGABRT is defined as 6, when the script processes the line #define SIGABRT 6 from <signal.h>, it will set msg[6] = "abort". Which would be fine. But SIGIOT is also defined as 6, so when it gets to processing that line, it will set msg[6] = "IOT instruction", replacing the previous string.

As a result, with zsh, the commonplace SIGABRT signal gets reported with the outlandish IOT instruction message. This is arguably a small bug in zsh. It's been reported as a Debian bug, but does not seem to have been reported upstream.

A side effect, which is a little more serious, is that kill -ABRT doesn't work under zsh; to send the abort signal you would have to kill -IOT instead, which probably nobody knows to do.

I've just sent a message to the zsh-workers mailing list about it.

like image 76
Nate Eldredge Avatar answered Dec 07 '25 23:12

Nate Eldredge