Skip to content

x86 Interop step-in causes exception from _controlfp_s in .NET 10 preview 5 #117389

@gregg-miskelly

Description

@gregg-miskelly

Description

In .NET 10 preview 5, there is a change so that when stepping from .NET -> C++ in Windows x86 code, something is changed in the floating point state such that when native code calls _controlfp_s, this triggers a ArithmeticException with message 'Overflow or underflow in the arithmetic operation.'

Reproduction Steps

  1. Extract x86InteropTest.zip
  2. Build the project for x86
  3. Open program.cs, and set a breakpoint on line 10
  4. Configure the project for mixed mode debugging
  5. Launch the project and wait for the breakpoint to hit
  6. After the breakpoint hits, step in
  7. The step in should land in the PrintDouble function in dllmain.cpp
  8. F5

Expected behavior

The program should run to completion

Actual behavior

The program stops at an ArithmeticException with message 'Overflow or underflow in the arithmetic operation.'

Call stack:

[System.ArithmeticException unhandled]
ntdll.dll!_ZwWaitForSingleObject@12() Line 157
	at minkernel\ntdll\wow6432\objfre\i386\usrstubs.asm(157)
KernelBase.dll!WaitForSingleObjectEx(void * hHandle, unsigned long dwMilliseconds, int bAlertable) Line 1328
	at minkernel\kernelbase\synch.c(1328)
ucrtbased.dll!_controlfp_s(unsigned int * _CurrentState, unsigned int newctrl, unsigned int mask) Line 54
	at minkernel\crts\ucrt\src\appcrt\tran\contrlfp.c(54)
ucrtbased.dll!`anonymous namespace'::fp_control_word_guard::~fp_control_word_guard() Line 38
	at minkernel\crts\ucrt\src\appcrt\convert\cfout.cpp(38)
ucrtbased.dll!__acrt_fltout(_CRT_DOUBLE value, unsigned int precision, __acrt_precision_style precision_style, _strflt * flt, char * result, unsigned int result_count) Line 366
	at minkernel\crts\ucrt\src\appcrt\convert\cfout.cpp(366)
ucrtbased.dll!fp_format_f(const double * const argument, char * const result_buffer, const unsigned int result_buffer_count, char * const scratch_buffer, const unsigned int scratch_buffer_count, const int precision, const __acrt_rounding_mode rounding_mode, __crt_cached_ptd_host & ptd) Line 661
	at minkernel\crts\ucrt\src\appcrt\convert\cvt.cpp(661)
ucrtbased.dll!__acrt_fp_format(const double * value, char * result_buffer, unsigned int result_buffer_count, char * scratch_buffer, unsigned int scratch_buffer_count, int format, int precision, unsigned __int64 options, __acrt_rounding_mode rounding_mode, __crt_cached_ptd_host & ptd) Line 841
	at minkernel\crts\ucrt\src\appcrt\convert\cvt.cpp(841)
ucrtbased.dll!__crt_stdio_output::output_processor<char,__crt_stdio_output::console_output_adapter<char>,__crt_stdio_output::format_validation_base<char,__crt_stdio_output::console_output_adapter<char>>>::type_case_a() Line 2459
	at minkernel\crts\ucrt\inc\corecrt_internal_stdio_output.h(2459)
ucrtbased.dll!__crt_stdio_output::output_processor<char,__crt_stdio_output::stream_output_adapter<char>,__crt_stdio_output::standard_base<char,__crt_stdio_output::stream_output_adapter<char>>>::state_case_type() Line 2076
	at minkernel\crts\ucrt\inc\corecrt_internal_stdio_output.h(2076)
ucrtbased.dll!__crt_stdio_output::output_processor<char,__crt_stdio_output::stream_output_adapter<char>,__crt_stdio_output::standard_base<char,__crt_stdio_output::stream_output_adapter<char>>>::process() Line 1704
	at minkernel\crts\ucrt\inc\corecrt_internal_stdio_output.h(1704)
ucrtbased.dll!common_vfprintf::__l2::<lambda>() Line 48
	at minkernel\crts\ucrt\src\appcrt\stdio\output.cpp(48)
ucrtbased.dll!__crt_seh_guarded_call<int>::operator()<void <lambda>(void),int <lambda>(void) &,void <lambda>(void)>(__acrt_lock_stream_and_call::__l2::void <lambda>(void) && setup, common_vfprintf::__l2::int <lambda>(void) & action, __acrt_lock_stream_and_call::__l2::void <lambda>(void) && cleanup) Line 204
	at VCCRT\vcruntime\inc\internal_shared.h(204)
ucrtbased.dll!__acrt_lock_stream_and_call<int <lambda>(void)>(_iobuf * const stream, common_vfprintf::__l2::int <lambda>(void) && action) Line 301
	at minkernel\crts\ucrt\inc\corecrt_internal_stdio.h(301)
ucrtbased.dll!common_vfprintf<__crt_stdio_output::standard_base,char>(const unsigned __int64 options, _iobuf * const stream, const char * const format, __crt_cached_ptd_host & ptd, char * const arglist) Line 37
	at minkernel\crts\ucrt\src\appcrt\stdio\output.cpp(37)
ucrtbased.dll!__stdio_common_vfprintf(unsigned __int64 options, _iobuf * stream, const char * format, __crt_locale_pointers * locale, char * arglist) Line 61
	at minkernel\crts\ucrt\src\appcrt\stdio\output.cpp(61)
NativeLib.dll!_vfprintf_l(_iobuf * const _Stream, const char * const _Format, __crt_locale_pointers * const _Locale, char * _ArgList) Line 645
	at C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt\stdio.h(645)
NativeLib.dll!printf(const char * const _Format, ...) Line 960
	at C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\ucrt\stdio.h(960)
NativeLib.dll!PrintDouble(double d) Line 23
	at C:\Users\greggm\Downloads\x86InteropTest\NativeLib\dllmain.cpp(23)
[Managed to Native Transition]
CsClient.dll!InteropCallstack.Program.Main(string[] args) Line 10
	at C:\Users\greggm\Downloads\x86InteropTest\CsClient\Program.cs(10)
...

Regression?

This is a regression from .NET 10 preview 3. It may have also worked in preview 4.

Known Workarounds

None

Configuration

.NET 10 preview 5 Windows x86

Other information

No response

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions