Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Illegal hardware instruction" from very simple code

While investigating a dubious claim, I wrote this little test program noway.c

int proveit()
{
    unsigned int n = 0;
    while (1) n++;
    return 0;
}

int main()
{
    proveit();
    return 0;
}

Testing this, I get:

$ clang -O noway.c
$ ./a.out
zsh: illegal hardware instruction  ./a.out

Wat.

If I compile without optimizations it hangs as expected. I looked at the assembly, and without all the bells and whistles the main function looks like this:

_main:                                  ## @main
    pushq   %rbp
    movq    %rsp, %rbp
    ud2

Where ud2 is apparently is an instruction specifically for undefined behavior. The aforementioned dubious claim, "A function that never returns is UB", is reinforced. I still find it hard to believe though. Really!? You can't safely write a spin loop?

So I guess my questions are:

  1. Is this a correct reading of what is going on?
  2. If so, can someone point me to some official resource that verifies it?
  3. What is a situation in which you would want this type of optimization to occur?

Relevant info

$ clang --version
Apple clang version 11.0.0 (clang-1100.0.20.17)
Target: x86_64-apple-darwin18.6.0
Thread model: posix
InstalledDir: /Applications/Xcode-beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
like image 248
luqui Avatar asked Nov 28 '19 00:11

luqui


1 Answers

If you get the ud2 for the code that is now in the question, then the compiler is not a conforming C compiler . You could report a compiler bug.

Note that in C++ this code would actually be UB. When threads were added (C11 and C++11 respectively), there was put in place a forward progress guarantee for any thread, including the main execution thread of a program that's not multi-threaded.

In C++ all threads must eventually progress, with no exceptions. However in C, a loop whose controlling expression is a constant expression is not required to progress. My understanding is that C added this exception because it was already common practice in embedded coding to use a while(1) {} to hang the thread.

Similar question with more detailed answers

like image 58
M.M Avatar answered Nov 14 '22 09:11

M.M