- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi.
I compiled the following code with icc12 and it aborts at run-time when pthread_exit tries to unwind the stack. The cause, as I understand it, is due to an empty call site table generated by icc12. In contrast, icc11.1 generates a proper table.
My compilation flags are -O2 -pthread, my code is
#include
#include
int counter;
class Guard {
public:
Guard() {
++counter;
}
~Guard() {
--counter;
}
};
void *handler_with_guard(void *)
{
Guard l;
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t t;
int result = pthread_create(&t, 0, handler_with_guard, 0);
printf("pthread_create result = %d\\n", result);
result = pthread_join(t, NULL);
printf("pthread_join result = %d\\n", result);
printf("counter = %d\\n", counter);
return 0;
}
The generated .gcc_except_table by icc12 is
.section .gcc_except_table, "a"
.align 4
_Z18handler_with_guardPv$$LSDA:
.byte 255
.byte 0
.uleb128 ..___tag_value__Z18handler_with_guardPv.24 - ..___tag_value__Z18handler_with_guardPv.23
..___tag_value__Z18handler_with_guardPv.23:
.byte 1
.uleb128 ..___tag_value__Z18handler_with_guardPv.22 - ..___tag_value__Z18handler_with_guardPv.21
..___tag_value__Z18handler_with_guardPv.21:
..___tag_value__Z18handler_with_guardPv.22:
.long 0x00000000,0x00000000
..___tag_value__Z18handler_with_guardPv.24:
The list of arguments to the icc are:
mcpcom -_g -mP3OPT_inline_alloca -D__HONOR_STD -D__ICC=1200 -D__INTEL_COMPILER=1200 -D_MT "-_Asystem(unix)" -D__ELF__ "-_Acpu(x86_64)" "-_Amachine(x86_64)" -D__INTEL_COMPILER_BUILD_DATE=20101116 -D__PTRDIFF_TYPE__=long "-D__SIZE_TYPE__=unsigned long" -D__WCHAR_TYPE__=int "-D__WINT_TYPE__=unsigned int" "-D__INTMAX_TYPE__=long int" "-D__UINTMAX_TYPE__=long unsigned int" -D__LONG_MAX__=9223372036854775807L -D__QMSPP_ -D_REENTRANT -D__OPTIMIZE__ -D__NO_MATH_INLINES -D__NO_STRING_INLINES -D__GNUG__=3 -D__GNUC__=3 -D__GNUC_MINOR__=4 -D__GNUC_PATCHLEVEL__=6 -D__NO_INLINE__ -D__i686 -D__i686__ -D__pentiumpro -D__pentiumpro__ -D__pentium4 -D__pentium4__ -D__tune_pentium4__ -D__MMX__ -D__LP64__ -D_LP64 -D_GNU_SOURCE=1 -D__DEPRECATED=1 -D__GXX_WEAK__=1 -D__GXX_ABI_VERSION=1002 "-D__USER_LABEL_PREFIX__= " -D__REGISTER_PREFIX__= -D__INTEL_RTTI__ -D__EXCEPTIONS=1 -D__SSE2__ -D__SSE__ -D__unix__ -D__unix -D__linux__ -D__linux -D__gnu_linux__ -B -Dunix -Dlinux -D__x86_64 -D__x86_64__ -_k -_8 -_l -_a -_b --gnu_version=346 -mGLOB_gcc_version=346 -_W5 --gcc-extern-inline -p --bool -tused -mGLOB_eh_linux -x --multibyte_chars --array_section --simd --simd_func --bool -mP1OPT_version=12.0-intel64 -mGLOB_diag_file=scopetest.diag -mP1OPT_print_version=FALSE -mCG_use_gas_got_workaround=F -mP2OPT_align_option_used=TRUE "-mGLOB_options_string=-O2 -pthread -S -v" -mGLOB_cxx_limited_range=FALSE -mIPOPT_activate -mIPOPT_lite -mGLOB_machine_model=GLOB_MACHINE_MODEL_EFI2 -mGLOB_product_id_code=0x22001de3 -mGLOB_extended_instructions=0x8 -mP3OPT_use_mspp_call_convention -mPGOPTI_value_profile_use=T -mP2OPT_il0_array_sections=TRUE -mGLOB_opt_level=2 -mP2OPT_hlo_level=2 -mP2OPT_hlo -mP2OPT_hpo_rtt_control=0 -mIPOPT_args_in_regs=0 -mIPOPT_obj_output_file_name=scopetest.o -mGLOB_linker_version=2.20 -mGLOB_long_size_64 -mGLOB_routine_pointer_size_64 -mP3OPT_asm_target=P3OPT_ASM_TARGET_GAS -mP3OPT_emit_asm_debug_info=1 -mGLOB_as_output_file=scopetest.s -mGLOB_source_dialect=GLOB_SOURCE_DIALECT_C_PLUS_PLUS -mP1OPT_source_file_name=scopetest.cpp scopetest.cpp
I compiled the following code with icc12 and it aborts at run-time when pthread_exit tries to unwind the stack. The cause, as I understand it, is due to an empty call site table generated by icc12. In contrast, icc11.1 generates a proper table.
My compilation flags are -O2 -pthread, my code is
#include
#include
int counter;
class Guard {
public:
Guard() {
++counter;
}
~Guard() {
--counter;
}
};
void *handler_with_guard(void *)
{
Guard l;
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t t;
int result = pthread_create(&t, 0, handler_with_guard, 0);
printf("pthread_create result = %d\\n", result);
result = pthread_join(t, NULL);
printf("pthread_join result = %d\\n", result);
printf("counter = %d\\n", counter);
return 0;
}
The generated .gcc_except_table by icc12 is
.section .gcc_except_table, "a"
.align 4
_Z18handler_with_guardPv$$LSDA:
.byte 255
.byte 0
.uleb128 ..___tag_value__Z18handler_with_guardPv.24 - ..___tag_value__Z18handler_with_guardPv.23
..___tag_value__Z18handler_with_guardPv.23:
.byte 1
.uleb128 ..___tag_value__Z18handler_with_guardPv.22 - ..___tag_value__Z18handler_with_guardPv.21
..___tag_value__Z18handler_with_guardPv.21:
..___tag_value__Z18handler_with_guardPv.22:
.long 0x00000000,0x00000000
..___tag_value__Z18handler_with_guardPv.24:
The list of arguments to the icc are:
mcpcom -_g -mP3OPT_inline_alloca -D__HONOR_STD -D__ICC=1200 -D__INTEL_COMPILER=1200 -D_MT "-_Asystem(unix)" -D__ELF__ "-_Acpu(x86_64)" "-_Amachine(x86_64)" -D__INTEL_COMPILER_BUILD_DATE=20101116 -D__PTRDIFF_TYPE__=long "-D__SIZE_TYPE__=unsigned long" -D__WCHAR_TYPE__=int "-D__WINT_TYPE__=unsigned int" "-D__INTMAX_TYPE__=long int" "-D__UINTMAX_TYPE__=long unsigned int" -D__LONG_MAX__=9223372036854775807L -D__QMSPP_ -D_REENTRANT -D__OPTIMIZE__ -D__NO_MATH_INLINES -D__NO_STRING_INLINES -D__GNUG__=3 -D__GNUC__=3 -D__GNUC_MINOR__=4 -D__GNUC_PATCHLEVEL__=6 -D__NO_INLINE__ -D__i686 -D__i686__ -D__pentiumpro -D__pentiumpro__ -D__pentium4 -D__pentium4__ -D__tune_pentium4__ -D__MMX__ -D__LP64__ -D_LP64 -D_GNU_SOURCE=1 -D__DEPRECATED=1 -D__GXX_WEAK__=1 -D__GXX_ABI_VERSION=1002 "-D__USER_LABEL_PREFIX__= " -D__REGISTER_PREFIX__= -D__INTEL_RTTI__ -D__EXCEPTIONS=1 -D__SSE2__ -D__SSE__ -D__unix__ -D__unix -D__linux__ -D__linux -D__gnu_linux__ -B -Dunix -Dlinux -D__x86_64 -D__x86_64__ -_k -_8 -_l -_a -_b --gnu_version=346 -mGLOB_gcc_version=346 -_W5 --gcc-extern-inline -p --bool -tused -mGLOB_eh_linux -x --multibyte_chars --array_section --simd --simd_func --bool -mP1OPT_version=12.0-intel64 -mGLOB_diag_file=scopetest.diag -mP1OPT_print_version=FALSE -mCG_use_gas_got_workaround=F -mP2OPT_align_option_used=TRUE "-mGLOB_options_string=-O2 -pthread -S -v" -mGLOB_cxx_limited_range=FALSE -mIPOPT_activate -mIPOPT_lite -mGLOB_machine_model=GLOB_MACHINE_MODEL_EFI2 -mGLOB_product_id_code=0x22001de3 -mGLOB_extended_instructions=0x8 -mP3OPT_use_mspp_call_convention -mPGOPTI_value_profile_use=T -mP2OPT_il0_array_sections=TRUE -mGLOB_opt_level=2 -mP2OPT_hlo_level=2 -mP2OPT_hlo -mP2OPT_hpo_rtt_control=0 -mIPOPT_args_in_regs=0 -mIPOPT_obj_output_file_name=scopetest.o -mGLOB_linker_version=2.20 -mGLOB_long_size_64 -mGLOB_routine_pointer_size_64 -mP3OPT_asm_target=P3OPT_ASM_TARGET_GAS -mP3OPT_emit_asm_debug_info=1 -mGLOB_as_output_file=scopetest.s -mGLOB_source_dialect=GLOB_SOURCE_DIALECT_C_PLUS_PLUS -mP1OPT_source_file_name=scopetest.cpp scopetest.cpp
Link Copied
8 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What happens when you initialize counter?
int counter = 0; // add " = 0"
In your posted code, counter is incremented (++) without initialization. The optimizer may have been tripped up by this.
Jim Dempsey
int counter = 0; // add " = 0"
In your posted code, counter is incremented (++) without initialization. The optimizer may have been tripped up by this.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It's my understanding that since it's a global counter, it should be 0 initialized (certainlly in C++ but even in C).
But, on the off chance that it wasn't, I tried adding the =0, and it made no difference.
After doing a bit more digging, it looks like the issue is cornered to extern "C". Icc12 assumes that everything declared as extern "C" will not trigger exception, so skipped in generating the call site entry for code that calls them.
But, on the off chance that it wasn't, I tried adding the =0, and it made no difference.
After doing a bit more digging, it looks like the issue is cornered to extern "C". Icc12 assumes that everything declared as extern "C" will not trigger exception, so skipped in generating the call site entry for code that calls them.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think there is bug in intel compiler.
I have submitted a report to intel compiler development team on this. I update this thread when I have more information.
You may use -O0 compiler option as a work arround for now.
I have submitted a report to intel compiler development team on this. I update this thread when I have more information.
You may use -O0 compiler option as a work arround for now.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I assume you extern "C"'d the thread function entry point.
extern "C" void *handler_with_guard(void *)
{
...
extern "C" void *handler_with_guard(void *)
{
...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Om. Thanks very much. I look forward to your update.
Sadly, -O0 doesn't work for us, since we need the compiler optimizations in the rest of our code, as it's a production system. Fortunately, we were able to find an alternative workaround:
if we write a trivial c++ wrapper for the functions, without inline or throw(), it seems icc decides it might generate an exception, and then everything works properly.
@jimdempseyatthecove - Yes, that's already been tried, and no, it doesn't make a difference. The issue is with pthread_exit, and will occur even if handler_with_guard is not the thread entry point.
Sadly, -O0 doesn't work for us, since we need the compiler optimizations in the rest of our code, as it's a production system. Fortunately, we were able to find an alternative workaround:
if we write a trivial c++ wrapper for the functions, without inline or throw(), it seems icc decides it might generate an exception, and then everything works properly.
@jimdempseyatthecove - Yes, that's already been tried, and no, it doesn't make a difference. The issue is with pthread_exit, and will occur even if handler_with_guard is not the thread entry point.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Any further updates, here?
Thanks.
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This may or may not be a related problem. I have been working on some code on Intel 64 that contains __asm blocks. In release mode the code failed. I noticed that the optimizaton defaulted to IPO enabled. So I thought that there may be a problem with the inlining of a function containing the __asm block. As a guess to the problem I added __declspec(noinline) the the function declaration and the resultant code worked as expected. I know your code does not have an __asm block, However, your code has an unusual exit from the called function (it exits the pthread thread). Try adding __declspec(noinline) the the function declaration.
Do notassume -noinline is equivilent to __declspec(noinline) as IPO may be overly aggressive.
Jim Dempsey
Do notassume -noinline is equivilent to __declspec(noinline) as IPO may be overly aggressive.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The issue has been resolved in latest Intel compiler 12.0. The compiler is available for download form https://registrationcenter.intel.com/.
Om
Om

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page