A
A
alex_justes2013-07-05 15:06:08
Programming
alex_justes, 2013-07-05 15:06:08

Strange behavior of the Intel C++ compiler?

While parsing one working project, I ran into a strange problem: the debug version "fell" with the error "Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call".
I began to figure it out ... I
came to this code, which crashes for absolutely the same reason:

#include <string.h>
void test()
{
  char a[10];
  char b[] = "test";
  strcpy_s(a, b);
  __try
  {
  }
  __except(1)
  {
  }
}
int main()
{
  test();
  return 0;
}

Compiler:
Intel® C++ Compiler for applications running on IA-32, Version 10.0 Build 20070426 Package ID: W_CC_P_10.0.025
Command line:
icl /c /Od /RTC1 /MDd /Gd main.cpp
xilink
main.obj that this is all compiled, there was such a problem: when the test() function is called, all the necessary memory on the stack is allocated at once, esp is saved to the stack, strcpy_s is called, esp is increased by 8 (we free stack memory), we restore the saved esp, esp is increased by the volume allocated memory at the beginning, compare esp with ebp -> Error!
The listing turned out like this (only the right place was left):
push      -1
push      OFFSET FLAT: _try_info_pack0
push      OFFSET FLAT: __except_handler3
push      eax
sub       esp, 3Ch
mov       DWORD PTR [ebp - 18h], esp
add       esp, 0
call      strcpy_s
add       esp, 8
mov       esp, DWORD PTR [ebp - 18h]
add       esp, 44h
cmp       ebp, esp
call      __RTC_CheckEsp

those. the analogy is this:
push eax;
mov dword ptr[ebp - 18h], esp;
pop eax;
mov esp, dword ptr[ebp - 18h];
cmp esp, ebp; // !!!!

The problem was solved like this: at the very beginning of the test () function, you can add the following insert:
__asm
{
  nop;
}

After that, the error disappears, the listing also shows that the code is now correct (the stack memory is allocated before calling strcpy_s, it is freed immediately after):
push      -1
push      OFFSET FLAT: _try_info_pack0
push      OFFSET FLAT: __except_handler3
push      eax
sub       esp, 34h
mov       DWORD PTR [ebp - 18h], esp
add       esp, -8
call      strcpy_s
add       esp, 8
mov       esp, DWORD PTR [ebp - 18h]
add       esp, 44h
cmp       ebp, esp
call      __RTC_CheckEsp

those. the analogy is this:
mov dword ptr[ebp - 18h], esp;
push eax;
pop eax;
mov esp, dword ptr[ebp - 18h];
cmp esp, ebp; // Теперь всё хорошо

I think this is a compiler error? Or is there a bug somewhere in my code?
PS
In compiler version 11.1.035 it compiles correctly, i.e. There is a suspicion that this is a jamb in the compiler.
Added:
The following code crashes for the same reason (when calling any function whose arguments are passed on the stack):
void t2(int a)
{
  return;
}
void t1()
{
  t2(10);
  __try
  {
  }
  __except(1)
  {
  }
}
int main()
{
  t1();
  return 0;
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
P
Paul, 2013-07-05
@Paul

It looks like a compiler bug. Did you buy an Intel Compiler? Write to support.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question