VS2010 - Breakpoint generates "Illegal Instruction" exception

VS2010 - Breakpoint generates "Illegal Instruction" exception

I have a small test project for boost serialize.

When running the release version of the test project the program runs till the end.

When setting a breakpoint in the release version in BoostSerialize.cpp line 332 then i get

"Unhandled exception at 0x00364645 in BoostSerialize.exe: 0xC000001D: Illegal Instruction."

I am using VS2010, Intel Compiler 14.0 SP1 and boost 1.54, static linked. boost is compiled with the following settings:
using intel : 14.0 : $(intel-compiler-14)/bin/ia32/icl.exe : <compatibility>vc10 <cxxflags>"/Qstd=c++11  /Qipo /Qdiag-disable:2586 /D_CRT_SECURE_NO_WARNINGS" ;

The test project is attached as zip file.

The problem can be reproduced on different PC's (Win7x64 pro, i7 and Xeon)

Bernhard

AllegatoDimensione
Download BoostSerialize - Copy.zip6.8 KB
52 post / 0 nuovi
Ultimo contenuto
Per informazioni complete sulle ottimizzazioni del compilatore, consultare l'Avviso sull'ottimizzazione

Please verify what Intel instruction set was selected to build the test-case.

For example, It is possible that AVX instruction set was selected by default but your CPU supports SSE4.1 instruction set.

There is no specific instructionset selected. The exception is only thrown when setting a breakpoint in line 332 of BoostSerialize.cpp.

Compile settings:

/I"C:\Libs\boost\boost_1_54_0\include" /Zi /nologo /W3 /O3 /Qipo /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /EHsc /GS /Zc:wchar_t /Zc:forScope /Fp"Release\BoostSerialize.pch" /Fa"Release\" /Fo"Release\" /Fd"Release\vc100.pdb" /Gd

Linker settings:

/OUT:"C:\project\spielwiese\BoostSerialize - Copy\Release\BoostSerialize.exe" /NOLOGO /LIBPATH:"C:\Libs\boost\boost_1_54_0\lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /MANIFEST /ManifestFile:"Release\BoostSerialize.exe.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"C:\project\spielwiese\BoostSerialize - Copy\Release\BoostSerialize.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86

When in the Debugger could you take a look at what instruction causes 0xC000001D exception?

It is usually signaled by CPU as a invalid opcode exception(can be related perhaps to prefixes).Could be caused by compiler while emmiting unsupported instruction.As Sergey advised please look at assembly code.

I verified project settings and detected one small issue: In Release Configuration a Linker Setting 'Generate Debug Info' is set to 'Yes' ( Actually, it is OK ).

My questions are: What instruction set do you need to support? AVX2? AVX? SSE4.1? Or something else?

Sorry for the long delay - i was some days not in the office.

When running the code on my desktop pc (Win7x64, Intel Xeon E5-1607) i got the following:

After selecting "Go to disassembly" i got the following message box:

and the assembler code:

Running the same per remote debugger on Win7x86 Embedded, Celeron Dual-Core T3100, i got the same result.

When running the program without any breakpoint everything works correct.

 

Bernhard, Could you attach these two pictures as external files ( Not as Media files )?

This is the assembler code when running on Intel Xeon E5-1607

   325:     save_data_binary(data_container,filename.c_str());
00B5462B  add         esp,0FFFFFFF0h  
00B5462E  lea         edx,[filename]  
00B54634  cmp         dword ptr [ebp-8Ch],10h  
00B5463B  lea         eax,[data_container]  
00B54641  db          0fh  
00B54642  inc         ebx  
   330:
   331:     // restore the data_container
   332:     test_data_container restored_data_container;
00B54643  xchg        eax,ebp  <== Breakpoint
00B54644  pushad  
00B54645  db          ffh             <== Instructionpointer
00B54646  db          ffh  
00B54647  dec         dword ptr [ecx+54892404h]  
00B5464D  and         al,4  
00B5464F  call        save_data_binary (0B610E0h)  
00B54654  add         esp,10h  
   326:     save_data_string(data_container,filename.c_str());
00B54657  add         esp,0FFFFFFF0h  
00B5465A  lea         edx,[filename]  
00B54660  cmp         dword ptr [ebp-8Ch],10h  
00B54667  lea         eax,[data_container]  
00B5466D  cmovae      edx,dword ptr [filename]  
00B54674  mov         dword ptr [esp],eax  
00B54677  mov         dword ptr [esp+4],edx  
00B5467B  call        save_data_string (0B60050h) 
 

>>>00B54645  db          ffh             <== Instructionpointer
00B54646  db          ffh  >>>

This looks like not properly disassembled code.Also pay attention to this machine code line >>>00B54647  dec         dword ptr [ecx+54892404h]>>> the offset looks a way to big.It seems that exception is thrown when the breakpoint is set.Do you know what breakpoint it is?I mean int 0x3 or writing to debug registers.

I suppose that compiler might have inserted two byte opcode of int 0x3 instruction.That's mean 0xCD03 instead of 0xCC.

Can you post machine code at this location?:00B54643 

I am thinking how to see what opcode of breakpoint was emmited by VS debugger.

>>00B54646 db ffh >>>
>>
>>This looks like not properly disassembled code...

Actually Yes and No since I had similar cases, that is, Illegal Instruction exception, on a system with Pentium 4 processor when by mistake I tried to execute an application compiled with support of AVX instructions. At the same time, Visual Studio 2008 really couldn't properly display disassembled codes since that version was released many years ago before AVX was released.

Possible reason is as follows:

There is an inconsistency related to codes generation between of your modules ( for example AVX ) and Boost binary modules ( located in C:\Libs\boost\boost_1_54_0\... folder, or so ), for example AVX2

Also, take into account that, for example:

#pragma intel optimization_parameter target_arch=AVX

or

#pragma intel optimization_parameter target_arch=AVX2

could be used in different source code files even if the main application is compiled with default architecture defined in a VS project as SSE or IA-32.

I deleted all breakpoints and started the program with F10 in VS2010. Then i attach with windgb to the process. Windbg shows the following assembler code:

00c745d7 83c4f0          add     esp,0FFFFFFF0h
00c745da 83fa10          cmp     edx,10h
00c745dd 8d9560ffffff    lea     edx,[ebp-0A0h]
00c745e3 0f439560ffffff  cmovae  edx,dword ptr [ebp-0A0h]
00c745ea 8d85c0fdffff    lea     eax,[ebp-240h]
00c745f0 890424          mov     dword ptr [esp],eax
00c745f3 89542404        mov     dword ptr [esp+4],edx
00c745f7 e8c4e30000      call    BoostSerialize!save_data_text (00c829c0)
00c745fc 83c410          add     esp,10h
00c745ff 83c4f0          add     esp,0FFFFFFF0h
00c74602 8d9560ffffff    lea     edx,[ebp-0A0h]
00c74608 83bd74ffffff10  cmp     dword ptr [ebp-8Ch],10h
00c7460f 8d85c0fdffff    lea     eax,[ebp-240h]
00c74615 0f439560ffffff  cmovae  edx,dword ptr [ebp-0A0h]
00c7461c 890424          mov     dword ptr [esp],eax
00c7461f 89542404        mov     dword ptr [esp+4],edx
00c74623 e888d00000      call    BoostSerialize!save_data_xml (00c816b0)
00c74628 83c410          add     esp,10h
00c7462b 83c4f0          add     esp,0FFFFFFF0h
00c7462e 8d9560ffffff    lea     edx,[ebp-0A0h]
00c74634 83bd74ffffff10  cmp     dword ptr [ebp-8Ch],10h
00c7463b 8d85c0fdffff    lea     eax,[ebp-240h]
00c74641 0f439560ffffff  cmovae  edx,dword ptr [ebp-0A0h]
00c74648 890424          mov     dword ptr [esp],eax
00c7464b 89542404        mov     dword ptr [esp+4],edx
00c7464f e88cca0000      call    BoostSerialize!save_data_binary (00c810e0)
00c74654 83c410          add     esp,10h
00c74657 83c4f0          add     esp,0FFFFFFF0h
00c7465a 8d9560ffffff    lea     edx,[ebp-0A0h]
00c74660 83bd74ffffff10  cmp     dword ptr [ebp-8Ch],10h
00c74667 8d85c0fdffff    lea     eax,[ebp-240h]
00c7466d 0f439560ffffff  cmovae  edx,dword ptr [ebp-0A0h]
00c74674 890424          mov     dword ptr [esp],eax
00c74677 89542404        mov     dword ptr [esp+4],edx
00c7467b e8d0b90000      call    BoostSerialize!save_data_string (00c80050)

after setting the breakpoint at line 332 within VS2010 windbg shows the following assembler code:

00c745d7 83c4f0          add     esp,0FFFFFFF0h
00c745da 83fa10          cmp     edx,10h
00c745dd 8d9560ffffff    lea     edx,[ebp-0A0h]
00c745e3 0f439560ffffff  cmovae  edx,dword ptr [ebp-0A0h]
00c745ea 8d85c0fdffff    lea     eax,[ebp-240h]
00c745f0 890424          mov     dword ptr [esp],eax
00c745f3 89542404        mov     dword ptr [esp+4],edx
00c745f7 e8c4e30000      call    BoostSerialize!save_data_text (00c829c0)
00c745fc 83c410          add     esp,10h
00c745ff 83c4f0          add     esp,0FFFFFFF0h
00c74602 8d9560ffffff    lea     edx,[ebp-0A0h]
00c74608 83bd74ffffff10  cmp     dword ptr [ebp-8Ch],10h
00c7460f 8d85c0fdffff    lea     eax,[ebp-240h]
00c74615 0f439560ffffff  cmovae  edx,dword ptr [ebp-0A0h]
00c7461c 890424          mov     dword ptr [esp],eax
00c7461f 89542404        mov     dword ptr [esp+4],edx
00c74623 e888d00000      call    BoostSerialize!save_data_xml (00c816b0)
00c74628 83c410          add     esp,10h
00c7462b 83c4f0          add     esp,0FFFFFFF0h
00c7462e 8d9560ffffff    lea     edx,[ebp-0A0h]
00c74634 83bd74ffffff10  cmp     dword ptr [ebp-8Ch],10h
00c7463b 8d85c0fdffff    lea     eax,[ebp-240h]
00c74641 0f43cc          cmovae  ecx,esp
00c74644 60              pushad
00c74645 ff              ???
00c74646 ff              ???

00c74647 ff8904248954    dec     dword ptr [ecx+54892404h]
00c7464d 2404            and     al,4
00c7464f e88cca0000      call    BoostSerialize!save_data_binary (00c810e0)
00c74654 83c410          add     esp,10h
00c74657 83c4f0          add     esp,0FFFFFFF0h
00c7465a 8d9560ffffff    lea     edx,[ebp-0A0h]
00c74660 83bd74ffffff10  cmp     dword ptr [ebp-8Ch],10h
00c74667 8d85c0fdffff    lea     eax,[ebp-240h]
00c7466d 0f439560ffffff  cmovae  edx,dword ptr [ebp-0A0h]
00c74674 890424          mov     dword ptr [esp],eax
00c74677 89542404        mov     dword ptr [esp+4],edx
00c7467b e8d0b90000      call    BoostSerialize!save_data_string (00c80050)

Now i see that VS2010 debugger is setting the breakpoint (int3 == 0xcc) at a complete wrong position.

But who is responsible for this behaviour? The debugger of VS2010 or the intel compiler (pdb files?) ?

@-->Sergey

Thanks to your hint.

I will check if #pragma intel optimization_parameter target_arch is used.

there is no #pragma intel in my sources of boost 1.54

>>...boost 1.54...

Here is another tip. Let's say your test application uses some Boost DLLs. Then, I would used MS Depends to verify exact names for these DLLs and then I would investigate how they are built and what Intel architectures are used.

Also,

If that magic Illegal instruction is located in the executable you've built then it looks like there is an issue on your side,

or

If that magic Illegal instruction is located in a Boost DLL, or a Boost static library (!), then it looks like there is an issue on Boost side

You need to pinpoint that exactly.

>>...boost 1.54...

Here is another tip. Let's say your test application uses some Boost DLLs. Then, I would used MS Depends to verify exact names for these DLLs and then I would investigate how they are built and what Intel architectures are used.

Also,

If that magic Illegal instruction is located in the executable you've built then it looks like there is an issue on your side,

or

If that magic Illegal instruction is located in a Boost DLL, or a Boost static library (!), then it looks like there is an issue on Boost side

You need to pinpoint that exactly.

>>>Actually Yes and No since I had similar cases, that is, Illegal Instruction exception, on a system with Pentium 4 processor when by mistake I tried to execute an application compiled with support of AVX instructions>>>

In your case it was expected because CPU did not recognize the AVX instructions encoding hence invalid instruction exception was thrown. 

>>>00c74645 ff              ???
00c74646 ff              ??? >>>

Is this a location of the breakpoint?

 

>>...In your case it was expected because CPU did not recognize the AVX instructions...

I've knew that and it was actually a tip to the user on what kind of issues to expect.

>>>Now i see that VS2010 debugger is setting the breakpoint (int3 == 0xcc) at a complete wrong position.

But who is responsible for this behaviour? The debugger of VS2010 or the intel compiler (pdb files?) ?>>>

At least you verified that used breakpoint is translated to 0xCC.Usually debugging thread opens process memory space and overwrites(inserts) the code with int3 opcodes.It could be also inserted by compiler when you have hardcoded breakpoints in your code.Possibly by using inline assembly or DebugBreak() function.

Take into account also Sergey's explanation it seems very logical.

>>>.Usually debugging thread opens process memory space and overwrites(inserts) the code with int3 opcodes.>>>

If you would like to see it in action you can simply start two instances of windbg.The first will insert the breakpoint at some memory address and next you can attach invasively second instance of the debugger to the first one so you will be able to see debug engine call stack.

>>...At least you verified that used breakpoint is translated to 0xCC...

I also would like to note that in essence the title of the thread is a little bit incorrect since a 'Breakpoint' action of any Visual Studio can't generate an Illegal Instruction exception and only unsupported instruction could generate it. Unfortunately I can't reproduce it since I don't use Boost at the moment and don't have a system with a CPU which supports AVX2 instruction set.

I hope that our generic advises helped you.

Actually there are some GP exceptions related to int3 and maybe it is possible that OS handler did not properly recognize the exact code meaning of the exception(pushed on the stack by CPU).Altough such scenario seems quite unlikely to happen.

At least you verified that used breakpoint is translated to 0xCC

I verified, that VS2010 is setting the int3 for the breakpoint at a wrong position. Is is not at the first byte of an opcode. It replaces the third byte of the opcode and that's the reason for getting an illegal instruction exception instead of hitting the breakpoint

correct code:

00c74641 0f439560ffffff  cmovae  edx,dword ptr [ebp-0A0h]

the same code with breakpoint set at byte 3 of opcode:

00c74641 0f43cc          cmovae  ecx,esp
00c74644 60              pushad
00c74645 ff              ???
00c74646 ff              ???

I can reproduce this behaviour on different plattforms and i have the same problem in a much bigger project also in the debug version.

 also inserted by compiler when you have hardcoded breakpoints in your code

I didn't use any hardcoded breakpoints

Yes you are right.I did not pay attention to this line of code 00c74641 0f43cc.VS debugger should have overwritten  that memory location with one 0xCC and two 0x90 instruction and failed to do so thus trigerred when executed invalid instruction exception.

Try to do the same with windbg and look at the result.

Quote:

iliyapolak wrote:

Try to do the same with windbg and look at the result.

This is a good idea. I will try it tomorrow morning at european time :-)

When setting the breakpoint then there is only replaced one byte of the opcode (0x95 with 0xcc).

>>...I verified, that VS2010 is setting the int3 for the breakpoint at a wrong position...

If this is the root cause of your problem then it has no relation to Intel Compiler 14.0 SP1 and Boost 1.54.

Hi Bernhard

Usually while overwriting or patching the existed instruction one must take into account the length of the patched instruction.In your case it is 3 bytes and int3 is represented by one byte opcode so the remaining space could be filled with nop or int3 opcodes.

Quote:

Sergey Kostrov wrote:

>>...I verified, that VS2010 is setting the int3 for the breakpoint at a wrong position...

If this is the root cause of your problem then it has no relation to Intel Compiler 14.0 SP1 and Boost 1.54.

Yes it seems that there is an error in memory patching/code patching in VS debugger module.It should be further verified and checked with the other debugger(windbg).

I tried to set in windbg the mentioned breakpoint at line 332. Then i got a box, where windbg offers me 3 addresses which can be used for the breakpoint (WinDbg - Setting breakpoint at line 332.bmp). The first address is the address of the opcode of cmovae with an offset of 2. That is the same address, where VS2010 set the wrong breakpoint. Windgb didn't set the breakpoint to the offered addresses.

Allegati: 

>>...When setting a breakpoint in the release...

I'd like to suggest you a very simple set of tests:

Step 1 - Create a new project without any static Boost libraries and make sure that it has the same Compiler and Linker settings as the project with Boost static library ( it could take 5-10 minutes to verify ). Take into account that project settings must be absolutely identical for cases 'Use Microsoft C++ compiler' and 'Use Intel C++ compiler' used in your project with Boost static libraries.

Step 2 - Add a couple of very simple code lines, like printf( ... ), _asm NOP and _mm_prefetch( NULL ). For example, a source code for the test could look like:

#include "xmmintrin.h"

int main( void )
{
/*
DebugBreak();
*/
printf( "Started\n" );
printf( "Step 1\n" );
_asm NOP
_asm NOP
_asm NOP
printf( "Step 2\n" );
_mm_prefetch( NULL );
_mm_prefetch( NULL );
_mm_prefetch( NULL );
printf( "Step 3\n" );
_asm NOP
_asm NOP
_asm NOP
printf( "Step 4\n" );
printf( "Completed\n" );
}

Step 3 - Switch to 'Use Microsoft C++ compiler' -> Build both configurations and verify that Breakpoints could be set and working in both Configurations.

Step 4 - Switch to 'Use Intel C++ compiler' -> Build both configurations and verify that Breakpoints could be set and working in both Configurations.

Step 5 - Uncomment a call to DebugBreak() function and repeat Steps 3 and Step 4.

Note 1: In assembler DebugBreak() function should look like:
...
int 3
ret
...
and simply go through that little function in two steps in order to return to main function.

Note 2: A similar set of tests could be repeated for the project with static Boost libraries

Note 3: It is possible that you will need to contact Microsoft if that problem is reproducible when 'Use Microsoft C++ compiler' is selected.

I have to use some boost functions - without this there will be no boost libs linked to the exe.

When i compile my boostserialize project with vs2010 compiler everything works. In this constellation i have no problems.

>>I have to use some boost functions - without this there will be no boost libs linked to the exe.
>>
>>When i compile my boostserialize project with vs2010 compiler everything works. In this constellation i have no problems.

In that case a complete VS 2010 test project ( which is set to 'Use Intel C++ compiler' ) needs to be uploaded to the thread to help an Intel Software Engineer with investigation. So, just upload the test project.

My understanding is it is possible that there is some incorrect codes generation in Release configuration but it needs to be confirmed on the Intel's side.

I still suggest you to complete a set of tests I've recommended as an additional verification.

>>...I still suggest you to complete a set of tests I've recommended as an additional verification...

If in 'Use Intel C++ compiler' case the exception is thrown in Release or Debug configurations than it is a sign that there is an issue with Intel C++ software.

It is interesting test,but when running inside VS environment when DebugBreak will be executed the same VS debugger will be notified about the breakpoint exception.The problem lies in patching code section of the running process and  your suggestion does not test any code patching.DebugBreak() function when compiled will be called from the main() and its code(int 0xcc) will not overwrite the other function existing code.

.>>> Windgb didn't set the breakpoint to the offered addresses.>>>

Can you post which command have you used?

You can also try to write directly memory space of the thread with the help of eb [some address] 0xcc command.

Quote:

iliyapolak wrote:

Can you post which command have you used?

I used the gui. I selected one after the other of the addresses in the message box. In the displayed source code i didn't see any red line and i didn't get an error message.

Quote:

Sergey Kostrov wrote:

In that case a complete VS 2010 test project ( which is set to 'Use Intel C++ compiler' ) needs to be uploaded to the thread to help an Intel Software Engineer with investigation. So, just upload the test project.

In the first post there is already a testproject attached.

@Bernhard

Another suggestion is to use debug registers that's mean simply choose to use ba command which will use debug register(DRn) to set the breakpoint.

Quote:

Bernhard Zellner wrote:

Quote:

iliyapolak wrote:

Can you post which command have you used?

 

I used the gui. I selected one after the other of the addresses in the message box. In the displayed source code i didn't see any red line and i didn't get an error message.

Use debugger prompt to enter the breakpoints.

Example:

~ThreadID bp [memory address of cmovae]

You can check pending breakpoints(which are set) with the command bl.

I have to clarify something.

In this thread i posted a debugging problem with VS2010 and intel compiler 14.0 SP1. I attached a small test project, where the problem can be reproduced exactly with this configuration and set the breakpoint in line 332. This small test project can be posted everywhere in the world. I have the same debugging problem with a much bigger project. But i can't post this project. It belongs to the company. I have to use VS2010 for my debugging and i would like to debug on source level, not on assembler level.

Does VS debugger failes to insert breakpoint also in your much bigger project?

>>...This small test project can be posted everywhere in the world...

Sorry, the thread is already so long that I forgot that the Test Project is attached to the initial post.

Quote:

iliyapolak wrote:

Does VS debugger failes to insert breakpoint also in your much bigger project?

I haven't proved it with windbg like i did it for the test project, but i have the same behaviour -> after setting a breakpoint, sometimes i get the "illegal instruction" exception

Seems that there could be a problem with linear or sequential disassembling of the machine code.Put it simply VS debugger cannot isolate single instruction from the code sequence. 

I think that the problem is produced by the compiler. WinDbg shows the same wrong address where Vs2010 is setting the breakpoint. Both debuggers are using the pdb files to have symbols.

AFAIK compiler is not involved in debugging process unless you are using inline assembly int3 or functions like DebugBreak().

 >>>WinDbg shows the same wrong address where Vs2010 is setting the breakpoint>>>

Have you tried to insert breakpoint from Windbg's prompt?

Quote:

iliyapolak wrote:

compiler is not involved in debugging process 

I think, the debugger uses the pdb files for getting information to do symbolic debugging -> pdb files are generated by the compiler -> if there are errors in the pdb file then the debugger will fail to do a correct job.

Why offers me windgb 3 addresses when trying to set the breakpoint (at line 332) on sourcecode level with the gui?

You could be right,although pdb files are probably not used when disassembling instruction stream.I suppose that at machine code granularity level linear disassembling is used.

Regarding Windbg breakpoint did you try to use windbg command prompt to set breakpoint and run the debuted to see the breakpoint hit?

You could be right,although pdb files are probably not used when disassembling instruction stream.I suppose that at machine code granularity level linear disassembling is used.

Regarding Windbg breakpoint did you try to use windbg command prompt to set breakpoint and run the debuted to see the breakpoint hit?

Pagine

Lascia un commento

Eseguire l'accesso per aggiungere un commento. Non siete membri? Iscriviti oggi