![]() |
Environment |
<<< Using Parasolid | Chapters | Floating-Point Traps >>> |
This chapter contains information specific to the different environments in which Parasolid is supported:
Note: Please ensure you check all the sections for information related to the platforms you use. Relevant platforms are clearly indicated at the start of each section. |
This section contains information for all platforms on the compiler and operating system used to build Parasolid. For details of the environments in which Parasolid can be run, see Section 6.3, “Supported operating systems and hardware”.
The sizes of the C types that are used in Parasolid interfaces (e.g., int, double and pointer) are defined by each platform’s compiler. Please see your compiler documentation for details, and remember that the size of pointers depends on your decision to compile for 32-bit or 64-bit code.
Since its creation, Parasolid has been written in a domain-specific language, which is “transpiled” to C code, and then compiled with each platform’s C compiler. The C compiler and options used are documented, to assist you with achieving compile and link compatibility with Parasolid.
At v34.1, we began to include C++ code within Parasolid. This means that some of its object files are generated by a C++ compiler, and some by a C compiler. Both compilers, and the options used with them, are described below. Note that on many platforms, the C and C++ compilers are different front-ends to a common code generator, and are thus often considered to be the same program.
You will need to ensure that Parasolid-based applications are linked against an appropriate C++ run-time library for each platform. If your applications already use C++, this is already taken care of. If not, linking using the C++ compiler is the best course of action.
At v34.1, C++ in Parasolid was compiled as C++11 (C++14 on Windows platforms). At v35.0, it is compiled as C++17. We hope to use C++20 from v36.0 onwards.
Since Parasolid’s interfaces are, and will remain, pure C, your applications are not required to use the same C++ standard as Parasolid. However, if your application code is complied using a different standard, check that the run-time libraries for that standard are compatible with the C++ standard used by Parasolid,
Because Parasolid is large, complex, extensively tested, and sensitive to changes in compilers, we take considerable care that all the computers used in developing and producing it have the same version of the compilers used for the relevant Parasolid platform. We very rarely change or update the compiler versions used for a given version and build of Parasolid after its release. We only do this if a compiler has serious bugs or other problems that make it impractical for further use.
For compilers that are frequently updated, such as Microsoft Visual Studio, we much prefer to use the initial release of each version of the compilers, because that provides greater assurance of upwards compatibility with later releases and updates.
This build uses SSE2 registers and instructions for improved performance.
Parasolid was compiled, linked and tested on 64-bit Windows 10 version 20H2. While it is built on a 64-bit operating system, it is 32-bit software for use in 32-bit applications. The compiler used was the Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28316 for x86, from Visual Studio 2019 v16.4.4.
The following compiler options were used:
/EHa /MD /Gs /D_X86_ /GF /GS /fp:precise /d2FH4- /arch:SSE2 /O2 /Qfast_transcendentals /D_WIN32_WINNT=_WIN32_WINNT_WIN7 |
/O2 |
|
/EHa |
(C++ only) Enable C++ error handing, including asynchronous exceptions. |
/d2FH4- |
(C++ only) Use traditional C++ unwind data, so as to be compatible with older versions of the Microsoft run-time library DLLs for Visual Studio. |
/Gs |
|
/MD |
Link with |
/GF |
|
/GS |
Use “GuardStack” stack protection, in compliance with the Microsoft SDL. See Section 6.5.9 and Section 6.6.2. |
/fp:precise |
|
/arch:SSE2 |
Compile for processors that support the SSE2 instruction set. |
/Qfast_transcendentals |
Use transcendental processor instructions, rather than library functions, for improved performance. |
/D_WIN32_WINNT=__WIN32_WINNT_WIN7 |
This build of Parasolid is compatible with all versions and updates of Visual Studio 2015 to 2022.Visual Studio 2019 v16.4.4
This build of Parasolid does not follow our normal practice of using the first release of a major version of Visual Studio, as described in Section 6.2.0.3, “Choice of compilers”. We were unable to use the initial release of Visual Studio 2019 because of an optimizer bug on the X64 WIN platform. See Section 6.2.2, “X64 WIN” for details of this.
This build uses SSE2 registers and instructions for improved performance.
Parasolid was compiled, linked and tested on 64-bit Windows 10 version 20H2. While it is built on a 64-bit operating system, it is 32-bit software for use in 32-bit applications. The C compiler used was the Microsoft (R) C/C++ Optimizing Compiler Version 19.30.30705 for x86, from Visual Studio 2019 v17.0.0.
The following compiler options were used:
/MD /Gs /D_X86_ /GF /GS /fp:precise /arch:SSE2 /O2 /options:strict/Qfast_transcendentals /D_WIN32_WINNT=_WIN32_WINNT_WIN7 |
The same compiler was used for C++, with the following options.
/EHa /MD /Gs /D_X86_ /GF /GS /fp:precise /arch:SSE2 /O2 /options:strict/std:c++17 /Qfast_transcendentals /D_WIN32_WINNT=_WIN32_WINNT_WIN7 |
/O2 |
|
/EHa |
(C++ only) Enable C++ error handing, including asynchronous exceptions. |
/std:c++17 |
|
/options:strict |
|
/Gs |
|
/MD |
Link with |
/GF |
|
/GS |
Use “GuardStack” stack protection, in compliance with the Microsoft SDL. See Section 6.5.9 and Section 6.6.2. |
/fp:precise |
|
/arch:SSE2 |
Compile for processors that support the SSE2 instruction set. |
/Qfast_transcendentals |
Use transcendental processor instructions, rather than library functions, for improved performance. |
/D_WIN32_WINNT=_WIN32_WINNT_WIN7 |
This build of Parasolid is compatible with all Update levels of Visual Studio 2019 and 2022. It requires Visual Studio 2019 or later run-time libraries, since it does not use the /d2FH4-option.
Parasolid was compiled, linked and tested on 64-bit Windows 10, version 20H2. The compiler used was the Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28316 for x64, from Visual Studio 2019 v16.4.4.
The following compiler options were used:
/EHa /MD /DWIN32 /DNDEBUG /d2FH4- /GF /W3 /O2 /fp:precise /fp:except /GS/favor:blend /D_WIN32_WINNT=_WIN32_WINNT_WIN7 |
/MD |
Link with |
/EHa |
(C++ only) Enable C++ error handing, including asynchronous exceptions. |
/d2FH4- |
(C++ only) Use traditional C++ unwind data, so as to be compatible with older versions of the Microsoft run-time library DLLs for Visual Studio. |
/GF |
|
/W3 |
|
/O2 |
|
/fp:precise |
|
/fp:except |
|
/GS |
Use “GuardStack” stack protection, in compliance with the Microsoft SDL. See Section 6.5.9 and Section 6.6.2. |
/favor:blend |
|
/D_WIN32_WINNT=__WIN32_WINNT_WIN7 |
This build of Parasolid is compatible with all versions and update levels of Visual Studio2015 to 2022.
This build of Parasolid does not follow our normal practice of using the first release of a major version of Visual Studio, as described in Section 6.2.0.3, “Choice of compilers”. We were unable to use the initial release of Visual Studio 2019 because of an optimizer bug on the X64 WIN platform. This needed to be fixed before we could be confident in Parasolid’s quality, and a fix was much more easily obtainable in v16.4 of Visual Studio 2019.
If you use Visual Studio 2019, we recommend that you use v16.4.4 or later, so as to avoid the bug we encountered. This was a problem with initialization of arrays passed as arguments to C functions. It did not happen often, but the circumstances where it did presented significant risks. If you need more details, please contact Parasolid Support.
Parasolid was compiled, linked and tested on 64-bit Windows 10, version 20H2. The C compiler used was the Microsoft (R) C/C++ Optimizing Compiler Version 19.30.30705 for x64, from Visual Studio 2019 v17.0.0.
The following compiler options were used:
/MD /DWIN32 /DNDEBUG /D_AMD64_ /GF /W3 /O2 /fp:precise /fp:except /GS/favor:blend /options:strict /D_WIN32_WINNT=_WIN32_WINNT_WIN7 |
The same compiler was used for C++, with the following options:
/EHa /MD /DWIN32 /DNDEBUG /D_AMD64_ /GF /W3 /O2 /fp:precise /fp:except /GS/favor:blend /options:strict /std:c++17 /D_WIN32_WINNT=_WIN32_WINNT_WIN7 |
/MD |
Link with |
/EHa |
(C++ only) Enable C++ error handing, including asynchronous exceptions. |
/std:c++17 |
|
/options:strict |
|
/GF |
|
/W3 |
|
/O2 |
|
/fp:precise |
|
/fp:except |
|
/GS |
Use “GuardStack” stack protection, in compliance with the Microsoft SDL. See Section 6.5.9 and Section 6.6.2. |
/favor:blend |
|
/D_WIN32_WINNT=_WIN32_WINNT_WIN7 |
This build of Parasolid is compatible with all Update levels of Visual Studio 2019 and 2022. It requires Visual Studio 2019 or later run-time libraries, since it does not use the /d2FH4-option.
Parasolid was compiled, linked and tested on 64-bit Windows 10 for ARM, version 21H2. The C compiler used was the Microsoft (R) C/C++ Optimizing Compiler Version 19.30.30705 for ARM64 from Visual Studio 2022 v17.0.0.
The following compiler options were used:
/MD /fp:precise /Qfast_transcendentals /D_ARM64_ /O2 /GS /Qspectre /D_WIN32_WINNT=_WIN32_WINNT_WIN7 /options:strict /GF /volatile:iso /W3 |
The same compiler was used for C++, with the following options:
/EHa /MD /fp:precise /Qfast_transcendentals /D_ARM64_ /O2 /GS /Qspectre/D_WIN32_WINNT=_WIN32_WINNT_WIN7 /std:c++17 /options:strict /GF/volatile:iso /W3 |
/MD |
Link with |
/EHa |
(C++ only) Enable C++ error handing, including asynchronous exceptions. |
/std:c++17 |
|
/fp:precise |
|
/Qfast_transcendentals |
Use transcendental processor instructions, rather than library functions, for improved performance. |
/D_WIN32_WINNT=__WIN32_WINNT_WIN7 |
|
/options:strict |
|
/O2 |
|
/GS |
Use “GuardStack” stack protection, in compliance with the Microsoft SDL. See Section 6.5.9 and Section 6.6.2. |
/Qspectre |
Use mitigations for the “Spectre” family of security problems. |
/GF |
|
/volatile:iso |
Use ISO C “volatile” semantics, rather than emulating the slower “MS” form. |
/W3 |
This build of Parasolid requires Visual Studio 2019 or later run-time libraries. It is compatible with all Update levels of Visual Studio 2022, and with Visual Studio 2019 v16.7 and later. However, we recommend that you use Visual Studio 2022 in preference to 2019, since that avoids compiler bugs we encountered with 2019, and the need to compile with a special pragma to avoid the use of “floating point contractions.” Do not use Visual Studio 2019 versions before v16.7 with this platform.
Parasolid was compiled, linked and tested on CentOS 7.9. The C compiler used was gcc version 7.3.1 from Red Hat Developer Toolset 7.1, with the following options:
-m64 -O2 -fno-strict-aliasing -fPIC -D_POSIX_SOURCE -fexceptions -std=c99 -Wformat -Wformat-security-fstack-protector-strong -fvisibility=hidden |
The same compiler was used for C++, with the
-std
option changed to
-std=c++17
.
-D_POSIX_SOURCE |
|
-std=c99 |
|
-std=c++17 |
|
-Wformat -Wformat-security |
Warn of security risks with the format strings used by the printf/scanf family of functions. |
-fstack-protector-strong |
Use improved stack protection. See Section 6.5.9 |
-fvisibility=hidden |
The Parasolid shared library is linked using three additional options for improved security:
Two more linking options are required to allow C++ exceptions to be thrown through Parasolid:
Tell the linker to use the shared GCC support library, for consistent exception handling across the application. |
|
Parasolid was compiled, linked and tested on Amazon Linux 2, version amzn2-kvm-2.0.20211005.0-arm64.xfs.gpt, with additional testing on Ubuntu Linux 20.04 LTS. The C compiler used was cc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-13), as supplied with Amazon Linux 2, with the following options:
-march=armv8-a -ffp-contract=off -O -fPIC -D_POSIX_SOURCE -D_POSIX_C_SOURCE=200112L -fexceptions -std=c99 -Wformat -Wformat-security -fstack-protector-strong -fno-strict-aliasing |
The same compiler was used for C++, with the
-std
option changed to
-std=c++17
.
Avoid the use of “floating-point contractions,” to improve consistency. |
|
-D_POSIX_SOURCE |
|
-D_POSIX_C_SOURCE |
|
-std=c99 |
|
-std=c++17 |
|
-Wformat -Wformat-security |
Warn of security risks with the format strings used by the printf/scanf family of functions. |
-fstack-protector-strong |
Use improved stack protection. See Section 6.5.9 |
|
The Parasolid shared library is linked using three additional options for improved security:
Two more linking options are required to allow C++ exceptions to be thrown through Parasolid:
Tell the linker to use the shared GCC support library, for consistent exception handling across the application. |
|
Parasolid was compiled, linked and tested on macOS 11.4. The C compiler used was Apple clang version 12.0.0 (clang-1200.0.32.27) from Xcode 12.2.
The following options were used:
The same compiler was used for C++, with the
-std
option changed to
-std=c++17
.
Compile and link for OS X 11.0 or later. See Section 6.6.9 |
|
Use improved stack protection. See Section 6.5.9 |
|
Make the partial availability warning into a compilation error. See Section 6.6.9, “MacOS and iOS backwards compatibility”. |
Parasolid was compiled, linked and tested on macOS 11.2. The C compiler used was Apple clang version 12.0.0 (clang-1200.0.32.27) from Xcode 12.2.
The following options were used:
The same compiler was used for C++, with the
-std
option changed to
-std=c++17
.
Compile and link for macOS 11.0 or later. See Section 6.6.9 |
|
Use improved stack protection. See Section 6.5.9 |
|
Make the partial availability warning into a compilation error. See Section 6.6.9, “MacOS and iOS backwards compatibility”. |
Parasolid was compiled, linked and tested on macOS 11.0. The C compiler used was Apple clang version 12.0.0 (clang-1200.0.32.27) from Xcode 12.2. Parasolid was tested on an iPad Pro with 6GB RAM, running iPadOS 13.5.
Please see Section 6.3.6 for expected changes to this platform’s build and test environment.
The following options were used:
The same compiler was used for C++, with the
-std
option changed to
-std=c++17
.
Compile and link for iOS 13.0 onwards. See Section 6.6.9. |
|
Use improved stack protection. See Section 6.5.9. |
|
Code intended for a dynamic library. This allows for building one in the future without changing the compiler options. |
|
Make the partial availability warning into a compilation error. See Section 6.6.9, “MacOS and iOS backwards compatibility”. |
Parasolid was compiled, linked and tested on macOS 11.0. The C compiler used was Apple clang version 12.0.0 (clang-1200.0.32.27) from Xcode 12.2. Parasolid was tested on the iOS Simulator from the same version of Xcode.
Please see Section 6.3.6 for expected changes to this platform’s build and test environment.
The following options were used:
The same compiler was used for C++, with the
-std
option changed to
-std=c++17
.
Compile and link for iOS 13.0 onwards. See Section 6.6.9. |
|
Use improved stack protection. See Section 6.5.9. |
|
Code intended for a dynamic library. This allows for building one in the future without changing the compiler options. |
|
Make the partial availability warning into a compilation error. See Section 6.6.9, “MacOS and iOS backwards compatibility”. |
We intend to keep the Intel iOS builds of Parasolid as similar as possible to the ARM iOS builds.
Parasolid was compiled and linked on CentOS 7.9. The C compiler used was Android clang version 9.0.8 (based on LLVM 9.0.8svn), from NDK21b for Linux. Parasolid was tested on a Xiaomi Black Shark 2 ‘phone, running Android 9.0.
The following compiler options were used:
|
The same compiler was used for C++, with the
-std
option changed to
-std=c++17
.
-std=c99 |
|
-std=c++17 |
|
-Wformat -Wformat-security |
Warn of security risks with the format strings used by the printf/scanf family of functions. |
-fstack-protector-strong |
Use improved stack protection. See Section 6.5.9. |
-fno-strict-aliasing |
The Parasolid shared library is linked using the following options:
Parasolid is no longer linked with “--hash-style=both” because all Android 9 and later implementations support “gnu” symbol table hashes.
This section describes the environments in which Parasolid can run for each platform. It contains information for all platforms.
Windows 7 is no longer supported by Microsoft, but several customers have asked us to keep Parasolid compatible with it, since they expect demand for it in the future. Therefore:
We intend to continue this scheme until the end of Microsoft support for Windows Server 2012 R2, described below. However, we cannot commit to this, because there is considerable potential for future changes to Windows, Visual Studio, virtual machine systems or security standards to make it impossible. We will, however, make all reasonable efforts to continue with it.
Windows 8.1 will cease to be supported by Parasolid on 10-JAN-2023. The related Windows Server 2012 R2 operating system will cease to be supported by Parasolid on 10-OCT-2023. In both cases, these dates are the end of Microsoft support for these operating systems.
We support Parasolid on the versions of Windows 10 and 11 that are still under support from Microsoft, including their server and embedded versions, where provided. We will cease supporting Parasolid on each version of Windows as and when Microsoft withdraws support for it. The currently supported versions are:
Parasolid will run on 32-bit or 64-bit supported versions of Windows.
Parasolid will run on any Intel or AMD x86 processor that supports the SSE2 instruction set.
Parasolid is built and tested on the traditional WIN32 desktop programming environment. It is not supported on the WinRT programming environment, or the Universal Windows Platform (UWP) environment, and is known not to work in those environments. It is not officially supported in Windows 10 applications for the Windows Store that make use of the Desktop Conversion Extension, but we would expect it to work in that environment.
The Parasolid DLL has additional version information, allowing you to confirm that you are using an SSE2 build via Windows Explorer. See Section 6.7, “Parasolid version information”, for more details.
Parasolid will run on 64-bit supported versions of Windows.
Parasolid will run on any Intel or AMD 64-bit x86 processor.
It is built for the traditional 64-bit WIN32 environment; see above for variant environments.
See Section 6.4.2, “X64 WIN” for details of the effects of the Visual Studio 2013 and later 64-bit math libraries when run on processors that support the AVX2 instruction set.
Parasolid runs on 64-bit supported versions of Windows for ARM, which started at version 1709. It is built for the 64-bit WIN32 environment; see above for variant environments.
See Section 5.6.1.5, “Processor affinity” for issues with processor affinity on ARM WIN.
Parasolid will run on any Intel or AMD 64-bit x86 processor. Parasolid is supported on CentOS 7, SUSE Linux Enterprise Desktop/Server version 12 or later, Red Hat Enterprise Linux 7 or later, and Ubuntu 20.04 LTS or later.
It should run on any x86-64 Linux with glibc 2.14 or later and the GCC 4.8 or later versions of libgcc_s and libstdc++, which are available in most versions of Linux distributed from 2014 onwards.
Parasolid will run on any 64-bit ARM processor. Parasolid is supported on Amazon Linux 2, SUSE Linux Enterprise Desktop/Server version 15, Red Hat Enterprise Linux 8 or later, and Ubuntu 20.04 LTS or later. It should run on any ARM64 Linux that has glibc 2.17 or later and the GCC 7 versions or later of libgcc_s and libstdc++.
When purchasing hardware for this platform, it is advisable to check in advance that it can boot and run your preferred Linux distribution. The booting arrangements for ARM-based platforms are not as standardized as they are on platforms derived from the IBM PC architecture. Our first set of hardware required us to use Ubuntu Linux as the master operating system, rather than the Red Hat or SUSE Enterprise operating systems we had used on Intel Linux.
Parasolid runs on macOS11.0 or later on any Intel-based Macintosh.
Parasolid runs on macOS 11.0 or later on any ARM-based “Apple Silicon” Macintosh.
Apple now provides two separate operating systems in the iOS family. These are iOS, for iPhones (and iPods) and iPadOS, for iPads. Although they use the same software development kits and tools, Apple does not provide any undertakings about compatibility between them. This change took place at iOS 13, which was accompanied by iPadOS 13. We develop and test Parasolid using iPad Pros, because they have more RAM than iPhones, and some of our test cases reach or exceed the RAM capacity of the largest currently available iPad Pros.
Since, by mobile device standards, a fully-featured solid-modeling application may use a lot of processor time and memory, we recommend that your apps require an iPad Pro with at least 4GB RAM.
Parasolid uses the basic ARMv8 64-bit instruction set, rather than any of the later enhanced instruction sets, so as to be compatible with older hardware.
Apple’s tvOS and watchOS are related to iOS, but use separate software development kits. We do not consider either to be relevant for Parasolid.
Parasolid runs on the iOS Simulator for iPadOS 13, 14 or 15, on any 64-bit Intel-based Macintosh with an appropriate version of Xcode installed. The warning for ARM iOS above also applies to this platform. We intend to keep the Intel iOS builds of Parasolid as similar as possible to the ARM iOS builds.
Parasolid runs on Android 9.0 or later on any ARM-based device running a 64-bit version of Android. Since, by mobile device standards, a fully-featured solid-modelling application may use a lot of processor time and memory, we recommend that your apps require a fast device with at least 4GB RAM.
Parasolid should also be runnable in the Android ARM emulator, although its size demands a powerful host machine, and our efforts have had limited success.
Parasolid uses the basic ARMv8 64-bit instruction set, rather than any of the later enhanced instruction sets, so as to be compatible with older hardware.
See also Section 6.6.10, “Android changes for NDK developers”.
Where practical, we recommend that you enable floating-point traps (that is, allow the operating system to catch run-time errors arising from floating-point operations).However, this is not practical on many of the supported platforms. See below for details of how to set up the recommended configurations on each platform, or the reasons why this is impractical.
The errors that we recommend that you enable traps for are:
You should also register a signal handler to handle the signal (SIGFPE) caught by the operating system in these cases; see Chapter 121, “Signal Handling” of the Functional Description manual for details.
For more information about floating-point traps, see Appendix A, “Floating-Point Traps”. For more information about floating-point traps and Parasolid SMP, see Section 5.6.3, “Run-time error handling”.
Parasolid is compiled with the
/fp:precise
option, which is the compiler’s default. Intel NT builds of Parasolid on older compilers used
/fp:fast
, which is slightly faster, but provides worse consistency. You can use either setting for your applications’ code, but
/fp:precise
is preferable, if its performance is acceptable.
Do not call Parasolid with the x87 floating-point unit set to any evaluation precision other than 53-bit precision (64-bit values), since it will only operate correctly with that setting. All floating-point values passed to, and returned from, Parasolid should be standard 64-bit values.The recommended floating-point traps are disabled by default on this platform. They can be enabled using code such as:
#include <float.h> _controlfp(_EM_DENORMAL | _EM_UNDERFLOW | _EM_INEXACT, _MCW_EM); |
Note that this line specifies those floating-point traps to be
disabled; all other traps are consequently enabled. You should consult the Microsoft documentation for
_controlfp()
before making use of this function.
Note that this Parasolid platform uses both x87 and SSE2 registers and instructions, but that Windows does not generate the SIGFPE signal when SSE2 instructions cause traps. It is reasonably simple to implement this yourself with some code in the
main()
function of your program: see Section 6.10, “Enabling SIGFPE for SSE2 on Intel NT”. Even if you do not use signals for error handling, see that section for details of the necessary calls to
_fpreset()
.
It is possible to use denormals as zeroes on this platform, and this gives a small improvement in performance. However, you may wish to avoid the practice. The SSE2 floating-point registers support them but the x87 registers do not; Parasolid uses both, with the choice for any individual calculation being made by the compiler. Our trials have been unable to detect any significant differences in Parasolid test results when using denormals as zeroes, but the possibility remains. To use denormals as zeroes, use the following call:
#include <float.h> _controlfp(_DN_FLUSH, _MCW_DN); |
The recommended floating-point traps are disabled by default on this platform. They are enabled by the line:
|
Note that this line specifies those floating-point traps to be
disabled; all other traps are consequently enabled. You should consult the Microsoft documentation for
_controlfp()
before making use of this function.
The use of denormals as zeroes is recommended on this platform and can be enabled with the following additional line:
#include <float.h> _controlfp(_DN_FLUSH, _MCW_DN); |
Parasolid is compiled to use the basic x86-64 instruction set, and does not use AVX, AVX2 or FMA3 instructions. However, Microsoft's 64-bit math library contains code paths that use FMA3 combined floating-point-multiply-add instructions. These paths will be used by default on processors that support them, such as the Intel “Haswell” series, AMD “Piledriver” series and their successors.
Microsoft's objective in this is increased performance, but Parasolid makes sufficiently few calls to the math library that this has no detectable effect on Parasolid's speed in our trials. However, the occasional slight differences in rounding caused by combining a multiply and an add into a single instruction can cause math library functions to produce slightly different results. These differences can cause a Parasolid modeling operation to fail where it would succeed on a processor without FMA3 instructions. In the same way, a Parasolid operation can succeed on a processor with FMA3 instructions when it would fail on a processor without them. These changes do not happen often (less than one in a thousand tests in our trials), but they are common enough to be noticed. Parasolid's algorithms are robust against most instances of such differences, but without human knowledge of what's “right” and what isn't, perfection is unattainable. The differences are similar in number and scope to those caused by a change of compilers, but depend on the hardware in use at run-time.
If you want to turn off the use of FMA3 instructions on processors that support them, you can do so with the line:
#include <math.h> _set_FMA3_enable(0); /* 0 = disable, 1 = enable */ |
Doing this only affects the process that makes the call to
_set_FMA3_enable()
, but it affects all code in that process that was built with the same version of Visual Studio. This happens because it is a setting within an individual run-time library, and different versions of Visual Studio can use different run-time libraries (However, Visual Studio 2015 to 2022 share the same run-time libraries, see Section 6.6.1, “Windows run-time libraries”).
You should consult the Microsoft documentation for
_set_FMA3_enable()
before making use of this function.
If your program contains code built with more than one version of Visual Studio that supports FMA3, then if you change this setting, you should change it in code compiled by each version of Visual Studio. If different run-time libraries are using different FMA3 settings, the calculations performed by code using different run-time libraries won’t be entirely consistent, which may have unpredictable results.
This issue, as of Visual Studio 2015 to 2022, only affects 64-bit code.
Floating-point traps are an optional feature of the ARM architecture, and Windows 10 for ARM does not allow them to be enabled.
This platform disables the recommended floating-point traps by default. You can enable them with the following code:
#include <fenv.h> feenableexcept( FE_OVERFLOW | FE_INVALID | FE_DIVBYZERO); |
Floating-point traps are an optional feature of the ARM architecture, and the Linux operating system has to be able to run with or without them, depending on hardware manufacturers’ choices. It manages this by always leaving them turned off, and does not supply a way for software to turn them on. The recommended floating-point traps thus cannot be enabled.
The recommended floating-point traps are disabled by default on this platform, and should not be enabled. The Clang compiler does not attempt to generate code that can safely be run with floating-point traps enabled. At optimization levels -O1 and -O2, it will sometimes move code that can cause a floating-point trap outside the scope of a test intended to prevent the trap.
Floating-point traps are an optional feature of the ARM architecture, and Apple’s ARM processors do not include them. The recommended floating-point traps thus cannot be enabled.
Floating-point traps are an optional feature of the ARM architecture, and Apple’s ARM processors do not include them. The recommended floating-point traps thus cannot be enabled.
The recommended floating-point traps are disabled by default on this platform. They should not be enabled, for the same reason as Intel MacOS.
Floating-point traps are an optional feature of the ARM architecture, and the Android operating system has to be able to run with or without them, depending on device manufacturers’ choices. It manages this by always leaving them turned off, and does not supply a way for apps to turn them on. The recommended floating-point traps thus cannot be enabled.
This section describes platform-specific issues and situations that you should avoid. It contains information on all relevant platforms.
We recommend that you build your applications as 64-bit code, for Windows 10 and later operating systems. If this is not practical, we recommend that you build as 32-bit code for Windows 10 and later.
If you wish to use this platform, note that all of your application has to be compiled as 32-bit code. Windows does not support mixing 32-bit and 64-bit code in the same program.
Parasolid is only provided for the arm64-v8a ABI. It is not possible to build Parasolid-based apps for any other Android ABI.
Do not use the
/Zp
compiler option, which modifies the Microsoft C/C++ compiler's structure packing rules. Parasolid is compiled with the Microsoft C/C++ compiler's default structure packing, and if structures compiled with different packing are passed to it, it will crash.
It is possible to build applications for these platforms with a different compiler to that used by Parasolid, although it is not recommended or officially supported. If you do this, any calls to the
matherr()
function made by the run-time library used by Parasolid will not be caught by your application, and FMA3 settings can be inconsistent between different parts of an application. See also Section 6.9, “Linking Windows run-time libraries”.
If you need to use a different NDK from Parasolid, we strongly recommend that you use clang and libc++. Note that the minimum Android API standard required by your app will be the highest API standard required by any of its components.
C++ applications built in the Visual Studio environment can’t, by default, handle signals. To do this, some non-default settings and some support code are required. Chapter 121, “Signal Handling”, in the Functional Description provides a detailed explanation of signal handling, and Microsoft’s documentation is the definitive reference on use of their tools. The steps needed to tie these things together are:
/EHa
option.
_set_se_translator()
. Note that this registration is thread specific, and thus needs to be done for every thread that enters Parasolid.Intel NT, X64 WIN, Intel Linux, and Intel MacOS
The Pentium 4 processor suffers from a problem referred to as the “64K aliasing conflict”. This problem causes the processor to run much slower than normal when dealing with memory addresses that are 64KB apart, or a multiple of 64KB.
This can be noticeable when running Parasolid-based applications on the Pentium 4, since Parasolid requests and uses memory in blocks of 128KB by default.
This affects all Parasolid-based applications running on Pentium 4 hardware, on any operating system.
There is a simple workaround: call PK_MEMORY_set_block_size with a number that is mutually prime with 64K. For example, the following code sets the block size to 128.5Kb.
PK_MEMORY_set_block_size( ((128*1024)+512) ); |
The Intel EM64T processors also suffer from an aliasing conflict, but on 4MB boundaries rather than 64KB, and with a lesser speed penalty.
X64 WIN, ARM WIN, Android, iOS and MacOS
X64 WIN and ARM WIN programs that use Parasolid always require more stack space than the default provided by the platform’s linker. Android, iOS and MacOS require larger than default stack sizes for application threads which will call Parasolid and for Parasolid internal SMP threads (on relevant platforms). See Section 5.5, “Stack sizes”, for more details.
Intel NT, Android, and ARM iOS
These platforms impose limitations on the amount of memory that can be used by software:
If you produce software for these platforms, we recommend that you take special care in testing for and handling out-of-memory conditions. This applies to Parasolid memory use in general, but meshes and lattices are especially likely to use large amounts of memory.
While this platform runs on ARM-based devices with no hard disk, Windows requires that such devices be capable of “swapping” data between physical memory and storage. ARM WIN programs are therefore not limited to the physical memory of the device they run on.
You will need to use the
-lpthread
parameter when linking, because the Parasolid library contains references to the POSIX threads library. See Section 5.6, “Symmetric Multi-Processing (SMP)” for details. On macOS, iOS, and Android platforms, the POSIX threads functions are included in the standard system library.
All of the platforms on which Parasolid is supported can use “stack protection”, also known as “buffer overflow protection” or “buffer overrun protection”, provided by the compiler. This is a safety precaution against attempts by computer viruses or other “malware” to take over a program.
A program’s stack is an area of memory, used to hold the local variables of the functions that make up the program. When a function is called, it usually uses stack memory for variables, and when it exits and returns to its caller, the memory used by those variables is freed for use by subsequent functions. The stack is also used to store the “return address” of each function call, the place where the caller function should resume running when the called function terminates.
If a program can be persuaded or tricked into storing more data in a variable on the stack than will fit, then this can overwrite the return address. The simplest way of doing this is to give a function that reads a string, from a file or a network message, a longer string than the variable will hold. If the function doesn’t check the length and stop when it reaches the limit, then it overwrites whatever lies beyond the variable, which is called “overrunning” the variable. Variables that hold strings are sometimes known as “buffers”.
The point of overwriting the return address is that when the function tries to return, it does so to an address controlled by whoever created the data that was read. This is why many security flaws can only be exploited via specially crafted files or network messages.
Stack protection systems work by means of compiler-inserted code at the start and end of vulnerable functions. The code at the start stores a hard-to-predict value (a “cookie” or “canary”) on the stack between the variables and the return address. The code at the end checks to see if the value has changed: if so, it is assumed that some variable has been overrun and the return address has been overwritten, corrupting the stack.
The usual response to a stack corruption is to terminate the program. It is not generally possible to recover from this condition, because there is no way to tell how far the corruption has spread.
Parasolid is compiled with the
/GS
(GuardStack) option, which implements stack protection, in accordance with the Microsoft Security Development Lifecycle (see Section 6.6.2).
If the protection code detects stack corruption, it generates an exception, which normally goes unhandled, and terminates the program. If you have a debugger installed, Windows will offer you the chance to debug the program, and the debugger will tell you that there has been a stack buffer overrun.
Parasolid is compiled with the
-fstack-protector-strong
option, which implements stack protection.
If the protection code detects stack corruption, it will output the message “stack smashing detected” to standard error. It will then call the run-time library function
abort()
. This will raise UNIX signal 6, SIGABRT, whose default handler will terminate the program. If you have installed a handler for this signal, it will be called. If your handler returns, or you have requested that SIGABRT be ignored, the program will be terminated.
Parasolid is compiled with the
-fstack-protector-strong
option, which implements stack protection.
If the protection code detects stack or heap corruption, your program will be terminated, and the message “Abort trap: 6” sent to standard error. This is done by raising UNIX signal 6, SIGABRT. It is not possible to trap this signal and report it differently, because the protection code disables any SIGABRT handler immediately before raising the signal.
Parasolid is compiled with the
-fstack-protector-strong
option, which implements stack protection.
If the protection code detects stack corruption, it will add the message “stack corruption detected” to the Android log, and send it to standard error. It will then call the run-time library function
abort()
. This will raise UNIX signal 6, SIGABRT, whose default handler will terminate the program. If you have installed a handler for this signal, it will be called. If your handler returns, or you have requested that SIGABRT be ignored, the program will be terminated.
Since Parasolid modeling operations can take significant amounts of time, and their duration can be hard to predict, it is important that you do not call Parasolid from the main thread of your app (on Android, the UI thread). If you do this, the application risks becoming unresponsive to messages from the operating system.
Create a separate thread to call Parasolid, and make sure it has sufficient stack space (see Section 5.5, “Stack sizes”).
This section describes additional relevant material that you will find useful.
Visual Studio 2015 marked an important change in Microsoft’s provision of run-time libraries. Before that version, each version of Visual Studio had its own version of the C/C++ run-time library, or “CRT”, and building programs that used a mixture of versions of Visual Studio required special care. Since Visual Studio 2015, all versions of Visual Studio have used the same filenames for their CRT:
The “Universal CRT”,
UCRT.DLL
.
api-ms-win-crt
family of DLLs, which provide access to the Universal CRT.
VCRUNTIME140.DLL
.
Visual Studios 2015 to 2022 are all “the same” compiler in some respects, since they all use the same CRT. Visual Studio 2019 added an additional file,
VCRUNTIME140_1.DLL
, to support improvements to C++.
Versions of Parasolid built with Visual Studio 2015 to 2019 will run correctly with the run-time libraries from Visual Studio 2015 to 2022.
Versions of Parasolid built with Visual Studio 2022 make use of the C++ improvements introduced at Visual Studio 2019, and thus require the run-time libraries from Visual Studio 2019 or 2022.
To be able to run programs that use Parasolid, you will need to install the relevant redistributable CRT. These are supplied with the relevant Visual Studio, and will be found, by default, in the following directories:
When you install Visual Studio 2022 on a computer that already has Visual Studio 2015, 2017 or 2019 run-time libraries installed, the older Visual Studio run-time libraries will apparently disappear from lists of installed programs. They have been replaced in the list by the Visual Studio 2022 run-time libraries, which will serve programs built with all versions of Visual Studio from 2015 onwards.
See also Section 6.9, “Linking Windows run-time libraries”.
Parasolid complies with the Microsoft Security Development Lifecycle. This is a set of standards intended to reduce the incidence of security vulnerabilities in Microsoft Windows applications. For full information on MS-SDL, see:
https://www.microsoft.com/security/sdl/default.aspx.
Microsoft recommends that all Windows software producers should use MS-SDL. We have done so because of customer requests. This does not make software perfectly secure, but it makes a would-be intruder’s task harder.
The following MS-SDL features have been implemented in Parasolid:
Parasolid DLLs for Windows platforms are linked with the
/NXCompat
linker option, to mark them as capable of running with DEP active. DEP is normally active on all versions of Windows supported by Parasolid, if all EXEs and DLLs used by a program are marked
/NXCompat
. Parasolid operates correctly with Data Execution Protection (DEP) checking active for Parasolid itself and the KID test harness.
Parasolid DLLs for Windows platforms are linked with the
/DynamicBase
linker option, to mark them as capable of running with the ASLR security measure, introduced at Windows Vista. This is only used if all EXEs and DLLs used by a program are marked
/DynamicBase
. Parasolid built with Visual Studio 2017 or later allows Windows to use more entropy with ASLR for 64-bit code, strengthening the protection.
ASLR can make it much harder to debug some kinds of code problems, notably bad pointers and memory overwrites. If you suspect that you are experiencing such problems, you can remove the
/DyamicBase
marker with:
editbin /DynamicBase:NO pskernel.dll |
Note that removing this marker will invalidate the Authenticode signature of the DLL. Do not distribute any DLLs that you have changed in this way; reserve them for debugging.
Parasolid DLLs for Windows platforms are linked with the
/SafeSEH
linker option, to ensure that they contain a table of all their Structured Exception Handling (SEH) exception handlers. This can be used by Windows as a countermeasure to new exception handlers being uploaded through security exploits.
This is a feature of all versions of Windows supported by Parasolid, which improves on /SafeSEH, but has to be turned on for each application on a desktop Windows system. It isn’t possible for Parasolid, which is a library, to turn it on, but we recommend that your products’ installers do so. For full details, see the “Let me enable it myself” section of:
https://support.microsoft.com/kb/956607
.
Parasolid is compiled with the GuardStack compiler option (
/GS
compiler option) so as to provide stack protection and comply with MS-SDL. We recommend that you consider using the
/GS
option for your application code. Code that performs network I/O is best compiled with the source pragma
#pragma strict_gs_check
.
Using GuardStack has increased the size of Parasolid, and reduced its speed, but both losses are less than 2%, after some optimization work. Parasolid Support can provide advice on reducing the performance losses on request.
Parasolid on Windows uses the secure string functions from ISO/IEC TR24731 (e.g.,
strcpy_s()
as required by MS-SDL), and no longer calls the traditional string functions banned by MS-SDL.
If the secure string functions detect a buffer overrun, they will generate an “Invalid Parameter Error”. We recommend that your applications should catch and report these errors, rather than simply terminating. See MSDN for details of invalid parameter errors and the function
_set_invalid_parameter_handler()
.
The run-time libraries for all versions of Visual Studio that can be used with Parasolid automatically terminate a program when they detect corruption of the memory heap.
MS-SDL recommends, but does not require, that function pointers be passed and stored in an encoded form. This has not been implemented in Parasolid, since it would create a large amount of work for all customers, even those who do not chose to implement MS-SDL, and would make Parasolid completely incompatible with earlier versions.
.NET DLLs are always built with
/DynamicBase
and
/NXCompat
; they don't contain SEH exception handlers.
The Parasolid DLLs supplied for these platforms contain two Windows icons: a Parasolid “program” icon and a Parasolid “document” icon. They may be used in the user interface of Parasolid-based programs.
The Parasolid DLLs for all the Windows platforms contain Authenticode® digital signatures (see MSDN). These signatures now use SHA-512 (or stronger) cryptographic hashes.
Parasolid is supplied as a dynamic library, or “dylib”. Its default install name is
./libpskernel.dylib
. Use
otool
with the
-L
option to check the install names in, or used by, a dylib or executable.
You can use the utility
install_name_tool
with the
-id
option to change the Parasolid dylib's install name to the path name and filename where your application will store the Parasolid library: the Parasolid dylib was linked with the
-
headerpad_max_install_names
option to allow for this. The reason for doing this is that the linker copies the install name in the Parasolid dylib into executables and dylibs that are linked against it. Therefore, if you change the name in the Parasolid dylib, you get the correct names in your own code automatically.
You can change the install name(s) that an executable (including
kid.exe
) uses for the dylibs it calls with the
-change
option of
install_name_tool
.
There are three special strings that may be useful to you when setting install names.
@executable_path
is replaced with the directory of the main executable of whatever program is loading the library.
@loader_path
is replaced with the directory of the executable or library that is loading the library.
@rpath
is replaced by the string(s) embedded in the application using the
-Wl,-rpath,<string>
option, and these string(s) may use
@loader_path
. Using these strings, it is possible to create applications that do not require installers and can be dragged and dropped into any directory. This follows the example of recent releases of Xcode, which is an exemplar of Apple’s application design. For more details, see “man Id” and “man dyld”.
Most operating systems have a way to limit the amount of virtual memory that can be used by the operating system. macOS does not. It provides a dialog that informs the user of excessive memory usage, but their only course of action is to kill off applications.
Incorrect requests to Parasolid can cause it to request very large quantities of memory from its frustrum. As a safety precaution, you may wish to have your frustrum keep a running total of memory allocated through it and refuse to allocate more than, say, four times the physical memory of the machine.
Since an iOS or Android device has no ability to “swap” memory out to its storage when an app tries to use too much memory, it is important that your Parasolid frustrum keeps a running total of memory allocated through it. Your app must set limits to prevent the frustrum allocating more memory than is available.
You may wish to use a similar memory limitation with the iOS Simulator. This is not mandatory, but it does make the simulator behave more like an iOS device.
We presume that Parasolid customers will want to make their applications compatible with Apple’s “Gatekeeper” security software. This requires signing all executables, dylibs, scripts, and other runnable parts of an application with an appropriate Apple signing certificate. Recent versions of Xcode can automate this process, and, by default, will apply the signature to everything signable in the application.
Parasolid family dylibs are not signed, and we do not currently intend to start signing them. This is because changing the install name of a library invalidates any signature. We feel it is important to give our customers the flexibility to set install names for whichever method they prefer their applications to use for locating libraries. Apple appear to regard signing as the final step of building a complete application, and Parasolid is a toolkit, not a complete application at all. See Section 6.6.5 above for details of setting install names.
Customers who download Parasolid from our website directly onto a Macintosh computer will find that the Parasolid dylib extracted from the
.tar.gz
file has a file-system attribute marking it as a quarantined file, created by the web browser and extraction tools. You should remove this attribute with the
xattr
command before building your application, since distributing a dylib with a quarantine attribute already on it is likely to cause confusion. See “man xattr” for details.
Apple’s system headers are annotated with the versions of macOS and iOS at which functions appear. The compiler uses the -
mmacosx-version-min
and -
mios-version-min
arguments to interpret those annotations.
Since macOS 10.12, and for all iOS and iPadOS versions, Parasolid is compiled with the -
Wpartial-availability
and -
Werror=partial-availability
options. These ensure that if functions were used that were not available at the minimum operating system to be supported, the calls would be treated as compilation errors.
For example, at Parasolid v35.0 the iOS builds of Parasolid are compiled for compatibility with iOS 13, using the iOS 14.2 headers supplied with Xcode 12.2. Using -Wpartial-availability and -Werror=partial-availability ensures that no calls to functions that aren’t available on iOS 13 can be compiled. This helps ensure that Parasolid is backwards compatible to iOS 13.
The Android project maintains a web page of issues that developers who use the Android NDK need to take account of, at:
https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md
Parasolid complies with all of them, as of the production of this document. Specifically, Parasolid:
dlopen()
. Parasolid has no ability to encrypt or decrypt anything. There are no cryptographic algorithms within it. We are documenting this because there are countries that impose restrictions on the import and/or export of cryptographic software.
The code signatures of Windows DLLs and the “Enhanced Strong Names” of the .NET binding DLLs make use of cryptography, but Parasolid does not contain any cryptographic functionality that makes use of them. External cryptographic software, normally provided with Windows, is required to validate those signatures.
Version information is embedded into Parasolid DLLs (for Windows platforms), shared libraries (for UNIX and Android platforms) and archive libraries (for UNIX, Android and iOS platforms). You can use this information to find out exactly which version of Parasolid you are using, for example, when reporting problems to Parasolid Support. This section explains what information is available, and how you can view it on all platforms on which Parasolid is supported.
To view the version information on Windows platforms, navigate to the Parasolid DLL using Windows Explorer. Right-click on the DLL file and select Properties, then click the Version tab.
Note: You can also hover the mouse pointer over the DLL file in Windows Explorer to display a subset of the available version information in a tool-tip popup window. |
On UNIX platforms and Android, use
what libpskernel.so
(or whatever the shared library is called on your platform: see Section 4.1.2). If your operating system lacks a
what
command, there are basic UNIX commands that can substitute:
strings libpskernel.so | grep ’@(#)’
For iOS archive libraries, use
what libpskernel_archive.a
, in the Terminal application of your development Mac.
The data items that are used are defined by the Windows VERSIONINFO resource, described in detail in the Microsoft Developer Network documentation library. Parasolid’s usage of Windows resources is described below; all those not mentioned are used in the same way on all platforms.
The source file used to generate the version information for Windows DLLs and UNIX and Android shared libraries is supplied in the relevant Parasolid release kits. For UNIX and Android platforms, it is
libpskernel_resources.c
, which defines a set of C strings to be found by the
what
command. For Windows platforms, it is
pskernel.rc
, a source file for the Microsoft Resource Compiler. Both of these files contain conditional compilation commands, to allow you to use them, if you need to create your own DLL or shared library, while allowing them to be distinguished from the libraries found in a Parasolid release kit.
You should not regard the information from version resources as described here as the definitive source of Parasolid version information. If it is inconsistent with the values returned by the function PK_SESSION_ask_kernel_version, you should always assume the function to be correct.
Bindings for using Parasolid in .NET programs are supplied with the Intel NT platform (32-bit .NET), and the X64 WIN platform (64-bit .NET). For details of the binding see Chapter 12, “Calling Parasolid From .NET Code” in the Parasolid Functional Description manual.
The bindings were compiled with the Microsoft (R) Visual C# Compiler, as supplied with Visual Studio and updated by Windows security updates. The bindings for Visual Studio 2019 builds require version 4.7.2 or later of the .NET framework. The bindings for Visual Studio 2022 builds require version 4.8 of the .NET framework.
These bindings will not work with any earlier version of C# or the .NET Framework.
The .NET Framework is not yet available for ARM WIN, and thus no binding is supplied.
This section explains various issues and restrictions that can apply to your use of the Microsoft C/C++ run-time library (“CRT”).
Parasolid is compiled with the
/MD
option, so that it uses the multi-threaded DLL version of the CRT. We recommend that you use the supplied Parasolid DLL,
pskernel.dll
, by linking its import library,
pskernel.lib
, rather than statically linking Parasolid.
It is simplest and best if your application is compiled using the same version of Visual Studio as Parasolid. The shipped version of your application should be compiled with the
/MD
option; this ensures Parasolid and your application are using the same copy of the CRT.
You will probably wish to create debug versions of your application for use during development, using the
/MDd
option. This makes your application use the debug multi-threaded DLL version of the CRT, which means that Parasolid and your application are linked against different copies of the CRT. This works correctly with Parasolid, because its frustrum architecture means that for many purposes (especially memory and file management) it is using your application's copy of the CRT, via function pointers provided by your application. Two caveats apply:
matherr()
function generated by Parasolid code will be made by Parasolid's copy of the CRT, and will not reach your application.
Please review the material on the
/MD
,
/MDd
,
/MT
and
/MTd
C/C++ compiler options in the MSDN documentation library before attempting to use any of the configurations described in this section.
If you wish to statically link Parasolid to your application, use the
pskernel_archive.lib
library. This only makes sense if all calls to Parasolid and all functions supplied to Parasolid from your application come from a single EXE or DLL, and your application is compiled with
/MD
. Trying to statically link Parasolid to code compiled with
/MDd
will not work, as the link will fail. You
cannot statically link Parasolid to code compiled with
/MT
or
/MTd
: again, the link will fail.
If you need to link your application statically to the CRT, compile it with
/MT
or
/MTd
and link against the DLL Parasolid using
pskernel.lib
. This configuration is not recommended; removing the need for static linking of the CRT is preferable.
It is possible to use a different version of Visual Studio for your application than the version that was used to build Parasolid. This is not supported, but has been successfully accomplished by several Parasolid customers. You should definitely use the Parasolid DLL, and remember that Parasolid and your application will be linked against different CRTs, as described above. The Parasolid frustrum architecture allows this to work, under normal circumstances, but care and testing will be required, and the caveats above apply.
Note: Visual Studio 2015 to 2022 all use the same CRT, as described in Section 6.6.1, “Windows run-time libraries”.This means that, for the purposes of this section, they can be treated as being the same version of Visual Studio. We do not know if this situation will continue for future versions of Visual Studio.Modern processors for the Intel NT platform have two separate sets of floating-point registers and instructions: the x87 set and the SSE2 set. Compilers may generate code that utilizes both sets of registers. The complexity of using both sets of registers, and the limited support of 32-bit Windows for SSE2 floating-point traps, means that some extra code is required for the traps to be handled well.
The
_controlfp()
function provided in the Visual Studio run-time library enables and disables floating-point traps for both the x87 and the SSE2 registers and instructions. You should consult the Microsoft documentation for
_controlfp()
before making use of this function.
32-bit versions of Windows (including the 32-bit emulation of Windows inside 64-bit Windows) do not generate SIGFPE, or any other signal, in response to SSE2 traps. They may produce a dialog box, or other error notification, claiming to have detected “multiple floating-point traps”.
This is produced by the Structured Exception Handling system (SEH), the underlying mechanism used by Windows for handling all hardware traps including access violations, integer divide-by-zero errors and floating-point traps. SEH is described in the MSDN documentation library; it works somewhat like C++ exceptions, but is quite separate from them.
You can convert SEH exceptions into signals by putting a SEH
__try
/
__except
block in the
main()
function of a C or C++ program:
This is an add-on to the normal method Windows uses for generating signals from hardware traps. If the program causes a hardware trap within the
__try{}
block, the operating system takes control of the thread that caused the trap and uses it to start executing SEH support code. This searches through the program’s stack looking for
__except(){}
blocks. This is not the same as C++ stack unwinding: while it is similar in that the stack is searched in the same manner, functions are not exited, destructors are not called, and so on. The search changes nothing itself: it merely searches.
Once the search has reached the
main()
function, the
__except
shown above gets control, and evaluates its “filter” expression: the part in
()
brackets. That calls the support function
generate_signals()
, which will be described below. If that function returns -indicating that it hasn’t handled the SEH exception - then the value EXCEPTION_CONTINUE_SEARCH is returned from the filter expression. The search then continues above
main()
, moving into the code in the C/C++ run-time library that calls
main()
to start the program. That has a
__try
/
__except
block that generates the default signals provides by the Microsoft run-time library.
This accepts the output of the special function
GetExceptionCode()
, which can only be called in the filter expression of an
__except
block, and which provides a value that specifies which SEH exception has happened. It can then simply call your program’s signal handler with an appropriate signal code.
This makes a direct call to the signal handler function that you registered via the
signal()
function, and completes the necessary action. This example code works in the same way as the code in the Microsoft C/C++ run-time library. The source code for that library is supplied with all versions of Visual Studio - although installing it is optional - and the files in it that implement signals are
winxfltr.c
and
crtexe.c
.
Your signal handler should call the Microsoft C/C++ run-time library function
_fpreset()
when it handles a SIGFPE generated by the Microsoft run-time library. Note that threads can cause traps and signals independently of each other, and there is nothing in the C or C++ run-time libraries that automatically tidies up other threads when one hits a trap. Parasolid multi-threading handles this: when a thread causes a signal to be generated, and the signal handler calls PK_SESSION_abort, the thread that caused the signal (and is now running the internal error handler) waits until all the other threads have either finished their work, or taken the chance to abort themselves, and then continues with aborting the Parasolid call.
SEH works with C++ code as well as C code, although it is best to compile C++ code with the
/EHa
option, to make sure that the optimizer does not discard code that could be needed under SEH.
If your version of Visual Studio does not catch SSE2 floating-point traps from 32-bit code, they can be added to it as follows:
STATUS_FLOAT_MULTIPLE_FAULTS
and
STATUS_FLOAT_MULTIPLE_TRAPS
.
STATUS_FLOAT_MULTIPLE_FAULTS
and
STATUS_FLOAT_MULTIPLE_TRAPS
as Win32 Exceptions, with their own names, and the hexadecimal codes from the Windows headers.<<< Using Parasolid | Chapters | Floating-Point Traps >>> |