You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/c-runtime-library/crt-initialization.md
+4-4Lines changed: 4 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -34,9 +34,9 @@ According to the C/C++ standard, `func()` must be called before `main()` is exec
34
34
35
35
One way to determine this is to set a breakpoint in `func()`, debug the application, and examine the stack. This is possible because the CRT source code is included with Visual Studio.
36
36
37
-
When you browse the functions on the stack, you will find that the CRT is looping through a list of function pointers and calling each one as it encounters them. These functions are either similar to `func()` or constructors for class instances.
37
+
When you browse the functions on the stack, you'll see that the CRT is looping through a list of function pointers and calling each one. These functions are similar to `func()`, or constructors for class instances.
38
38
39
-
The CRT obtains the list of function pointers from the Microsoft C++ compiler. When the compiler sees a global initializer, it generates a dynamic initializer in the `.CRT$XCU` section (where `CRT` is the section name and `XCU` is the group name). To obtain a list of those dynamic initializers run the command **dumpbin /all main.obj**, and then search the `.CRT$XCU` section (when main.cpp is compiled as a C++ file, not a C file). It will be similar to the following:
39
+
The CRT gets the list of function pointers from the Microsoft C++ compiler. When the compiler sees a global initializer, it generates a dynamic initializer in the `.CRT$XCU` section where `CRT` is the section name and `XCU` is the group name. To obtain a list of dynamic initializers, run the command **dumpbin /all main.obj**, and then search the `.CRT$XCU` section. This applies when main.cpp is compiled as a C++ file, not a C file.. It will be similar to the following:
40
40
41
41
```
42
42
SECTION HEADER #6
@@ -70,7 +70,7 @@ The CRT defines two pointers:
70
70
71
71
-`__xc_z` in `.CRT$XCZ`
72
72
73
-
Both groups do not have any other symbols defined except `__xc_a` and `__xc_z`.
73
+
Neither group has any other symbols defined except `__xc_a` and `__xc_z`.
74
74
75
75
Now, when the linker reads various `.CRT` groups, it combines them in one section and orders them alphabetically. This means that the user-defined global initializers (which the Microsoft C++ compiler puts in `.CRT$XCU`) will always come after `.CRT$XCA` and before `.CRT$XCZ`.
76
76
@@ -86,7 +86,7 @@ The section will resemble the following:
86
86
__xc_z
87
87
```
88
88
89
-
So, the CRT library uses both `__xc_a` and `__xc_z` to determine the start and end of the global initializers list because of the way in which they are laid out in memory after the image is loaded.
89
+
So, the CRT library uses both `__xc_a` and `__xc_z` to determine the start and end of the global initializers list because of the way in which they're laid out in memory after the image is loaded.
The Microsoft run-time library provides many routines that are useful for creating different versions of a program for international markets. This includes [locale-related routines](../c-runtime-library/locale.md), wide-character routines, multibyte-character routines, and generic-text routines. For convenience, most locale-related routines are also categorized in this reference according to the operations they perform. In this section and in the alphabetic reference, multibyte-character routines and wide-character routines are described with single-byte-character counterparts, where they exist.
12
+
The Microsoft runtime library provides many routines that you can use to customize your app for international markets. This includes [locale-related routines](../c-runtime-library/locale.md), wide-character routines, multibyte-character routines, and generic-text routines.
13
+
14
+
For convenience, most locale-related routines are also categorized according to what they do. In this section and in the alphabetic reference, multibyte-character routines and wide-character routines are described with their single-byte-character counterparts, when they exist.
12
15
13
-
Also included are the ISO646 operator alternatives.
16
+
ISO646 operator alternatives are also included.
14
17
15
18
## See also
16
19
17
-
[Universal C runtime routines by category](../c-runtime-library/run-time-routines-by-category.md)<br/>
20
+
[Universal C runtime routines by category](../c-runtime-library/run-time-routines-by-category.md)
Most of the security-enhanced CRT functions and many of the preexisting functions validate their parameters. This could include checking pointers for **NULL**, checking that integers fall into a valid range, or checking that enumeration values are valid. When an invalid parameter is found, the invalid parameter handler is executed.
11
+
Most of the security-enhanced CRT functions, and many of the the un-enhanced versions, validate their parameters for things like: checking pointers for **NULL**, checking that integers fall into a valid range, or checking that enumeration values are valid. If an invalid parameter is found, the invalid parameter handler is executed.
12
12
13
13
## Invalid Parameter Handler Routine
14
14
15
-
When a C Runtime Library function detects an invalid parameter, it captures some information about the error, and then calls a macro that wraps an invalid parameter handler dispatch function, one of [_invalid_parameter](../c-runtime-library/reference/invalid-parameter-functions.md), [_invalid_parameter_noinfo](../c-runtime-library/reference/invalid-parameter-functions.md), or [_invalid_parameter_noinfo_noreturn](../c-runtime-library/reference/invalid-parameter-functions.md). The dispatch function called depends on whether your code is, respectively, a debug build, a retail build, or the error is not considered recoverable.
15
+
When a C Runtime Library function detects an invalid parameter, it captures some information about the error, and then calls a macro that wraps an invalid parameter handler dispatch function, one of [_invalid_parameter](../c-runtime-library/reference/invalid-parameter-functions.md), [_invalid_parameter_noinfo](../c-runtime-library/reference/invalid-parameter-functions.md), or [_invalid_parameter_noinfo_noreturn](../c-runtime-library/reference/invalid-parameter-functions.md). The dispatch function called depends on whether your code is, respectively, a debug build, a retail build, or the error isn't considered recoverable.
16
16
17
17
In Debug builds, the invalid parameter macro usually raises a failed assertion and a debugger breakpoint before the dispatch function is called. When the code is executed, the assertion may be reported to the user in a dialog box that has "Abort", "Retry", and "Continue" or similar choices, depending on the operating system and runtime library version. These options allow the user to immediately terminate the program, to attach a debugger, or to let the existing code continue to run, which calls the dispatch function.
18
18
19
-
The invalid parameter handler dispatch function in turn calls the currently assigned invalid parameter handler. By default, the invalid parameter calls `_invoke_watson` which causes the application to "crash," that is, terminate and generate a mini-dump. If enabled by the operating system, a dialog box asks the user if they want to load the crash dump to Microsoft for analysis.
19
+
The invalid parameter handler dispatch function in turn calls the currently assigned invalid parameter handler. By default, the invalid parameter calls `_invoke_watson`, which causes the application to close and generate a mini-dump. If enabled by the operating system, a dialog box asks the user if they want to send the crash dump to Microsoft for analysis.
20
20
21
21
This behavior can be changed by using the functions [_set_invalid_parameter_handler](../c-runtime-library/reference/set-invalid-parameter-handler-set-thread-local-invalid-parameter-handler.md) or [_set_thread_local_invalid_parameter_handler](../c-runtime-library/reference/set-invalid-parameter-handler-set-thread-local-invalid-parameter-handler.md) to set the invalid parameter handler to your own function. If the function you specify does not terminate the application, control is returned to the function that received the invalid parameters. In the CRT, these functions will normally cease function execution, set `errno` to an error code, and return an error code. In many cases, the `errno` value and the return value are both `EINVAL`, indicating an invalid parameter. In some cases, a more specific error code is returned, such as `EBADF` for a bad file pointer passed in as a parameter. For more information on `errno`, see [errno, _doserrno, _sys_errlist, and _sys_nerr](../c-runtime-library/errno-doserrno-sys-errlist-and-sys-nerr.md).
22
22
23
23
## See also
24
24
25
-
[Security Features in the CRT](../c-runtime-library/security-features-in-the-crt.md)<br/>
25
+
[Security Features in the CRT](../c-runtime-library/security-features-in-the-crt.md)\
Copy file name to clipboardExpand all lines: docs/c-runtime-library/potential-errors-passing-crt-objects-across-dll-boundaries.md
+11-5Lines changed: 11 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -1,14 +1,14 @@
1
1
---
2
2
title: "Potential Errors Passing CRT Objects Across DLL Boundaries"
3
-
description: "An overview of potential problems you may encounter when passing Microsoft C runtime objects across a dynamic link library (DLL) boundary."
3
+
description: "An overview of potential problems you may come across when passing Microsoft C runtime objects across a dynamic link library (DLL) boundary."
4
4
ms.date: "11/04/2016"
5
5
ms.topic: "conceptual"
6
6
helpviewer_keywords: ["DLL conflicts [C++]"]
7
7
ms.assetid: c217ffd2-5d9a-4678-a1df-62a637a96460
8
8
---
9
9
# Potential Errors Passing CRT Objects Across DLL Boundaries
10
10
11
-
When you pass C Run-time (CRT) objects such as file handles, locales, and environment variables into or out of a DLL (function calls across the DLL boundary), unexpected behavior can occur if the DLL, as well as the files calling into the DLL, use different copies of the CRT libraries.
11
+
When you pass C Run-time (CRT) objects such as file handles, locales, and environment variables into or out of a DLL (function calls across the DLL boundary), unexpected behavior can occur if the DLL, and files that call into the DLL, use different copies of the CRT libraries.
12
12
13
13
A related problem can occur when you allocate memory (either explicitly with `new` or `malloc`, or implicitly with `strdup`, `strstreambuf::str`, and so on) and then pass a pointer across a DLL boundary to be freed. This can cause a memory access violation or heap corruption if the DLL and its users use different copies of the CRT libraries.
14
14
@@ -18,17 +18,23 @@ HEAP[]: Invalid Address specified to RtlValidateHeap(#,#)
18
18
19
19
## Causes
20
20
21
-
Each copy of the CRT library has a separate and distinct state, kept in thread local storage by your app or DLL. As such, CRT objects such as file handles, environment variables, and locales are only valid for the copy of the CRT in the app or DLL where these objects are allocated or set. When a DLL and its app clients use different copies of the CRT library, you cannot pass these CRT objects across the DLL boundary and expect them to be picked up correctly on the other side. This is particularly true of CRT versions before the Universal CRT in Visual Studio 2015 and later. There was a version-specific CRT library for every version of Visual Studio built with Visual Studio 2013 or earlier. Internal implementation details of the CRT, for example, its data structures and naming conventions, were different in each version. Dynamically linking code compiled for one version of the CRT to a different version of the CRT DLL has never been supported, though occasionally it would work, more by luck than by design.
21
+
Each copy of the CRT library has a separate and distinct state, kept in thread local storage by your app or DLL.
22
22
23
-
Also, because each copy of the CRT library has its own heap manager, allocating memory in one CRT library and passing the pointer across a DLL boundary to be freed by a different copy of the CRT library is a potential cause for heap corruption. If you design your DLL so that it passes CRT objects across the boundary or allocates memory and expects it to be freed outside the DLL, you restrict the app clients of the DLL to use the same copy of the CRT library as the DLL. The DLL and its clients normally use the same copy of the CRT library only if both are linked at load time to the same version of the CRT DLL. Because the DLL version of the Universal CRT library used by Visual Studio 2015 and later on Windows 10 is now a centrally deployed Windows component, ucrtbase.dll, it is the same for apps built with Visual Studio 2015 and later versions. However, even when the CRT code is identical, you can't hand off memory allocated in one heap to a component that uses a different heap.
23
+
CRT objects such as file handles, environment variables, and locales are only valid for the copy of the CRT in the app or DLL where these objects are allocated or set. When a DLL and its app clients use different copies of the CRT library, you can't pass these CRT objects across the DLL boundary and expect them to be used correctly on the other side. This is true of CRT versions before the Universal CRT in Visual Studio 2015 and later.
24
+
25
+
There was a version-specific CRT library for every version of Visual Studio built with Visual Studio 2013 or earlier. Internal implementation details of the CRT, such as data structures and naming conventions, were different in each version. Dynamically linking code that was compiled for one version of the CRT to a different version of the CRT DLL has never been supported. Occasionally it would work, but due to luck rather than design.
26
+
27
+
Because each copy of the CRT library has its own heap manager, allocating memory in one CRT library and passing the pointer across a DLL boundary to be freed by a different copy of the CRT library can cause heap corruption. If you design your DLL so that it passes CRT objects across the DLL boundary, or allocates memory and expects it to be freed outside the DLL, app clients of the DLL must use the same copy of the CRT library as the DLL.
28
+
29
+
The DLL and its clients normally use the same copy of the CRT library only if both are linked at load time to the same version of the CRT DLL. Because the DLL version of the Universal CRT library used by Visual Studio 2015, and later on Windows 10, is now a centrally deployed Windows component (ucrtbase.dll), it is the same for apps built with Visual Studio 2015 and later versions. However, even when the CRT code is identical, you can't hand off memory allocated in one heap to a component that uses a different heap.
24
30
25
31
## Example
26
32
27
33
### Description
28
34
29
35
This example passes a file handle across a DLL boundary.
30
36
31
-
The DLL and .exe file are built with /MD, so they share a single copy of the CRT.
37
+
The DLL and .exe files are built with /MD, so they share a single copy of the CRT.
32
38
33
39
If you rebuild with /MT so that they use separate copies of the CRT, running the resulting test1Main.exe results in an access violation.
Any Microsoft MBCS run-time library routine that handles only one multibyte character or one byte of a multibyte character expects an **`unsigned int`** argument (where 0x00 <= character value <= 0xFFFF and 0x00 <= byte value <= 0xFF). An MBCS routine that handles multibyte bytes or characters in a string context expects a multibyte-character string to be represented as an **`unsigned char`** pointer.
12
+
Any Microsoft MBCS run-time library routine that handles only 1 multibyte character or 1 byte of a multibyte character expects an **`unsigned int`** argument (where 0x00 <= character value <= 0xFFFF and 0x00 <= byte value <= 0xFF). An MBCS routine that handles multibyte bytes or characters in a string context expects a multibyte-character string to be represented as an **`unsigned char`** pointer.
13
13
14
14
> [!CAUTION]
15
15
> Each byte of a multibyte character can be represented in an 8-bit **`char`**. However, an SBCS or MBCS single-byte character of type **`char`** with a value greater than 0x7F is negative. When such a character is converted directly to an **`int`** or a **`long`**, the result is sign-extended by the compiler and can therefore yield unexpected results.
16
16
17
-
Therefore it is best to represent a byte of a multibyte character as an 8-bit **`unsigned char`**. Or, to avoid a negative result, simply convert a single-byte character of type **`char`** to an **`unsigned char`** before converting it to an **`int`** or a **`long`**.
17
+
It's best to represent a byte of a multibyte character as an 8-bit **`unsigned char`**. Or, to avoid a negative result, convert a single-byte character of type **`char`** to an **`unsigned char`** before converting it to an **`int`** or a **`long`**.
18
18
19
19
Because some SBCS string-handling functions take (signed) **`char`**<strong>\*</strong> parameters, a type mismatch compiler warning will result when **_MBCS** is defined. There are three ways to avoid this warning, listed in order of efficiency:
20
20
21
21
1. Use the type-safe inline functions in TCHAR.H. This is the default behavior.
22
22
23
-
1. Use the direct macros in TCHAR.H by defining **_MB_MAP_DIRECT** on the command line. If you do this, you must manually match types. This is the fastest method but is not type-safe.
23
+
1. Use the direct macros in TCHAR.H by defining **_MB_MAP_DIRECT** on the command line. If you do this, you must manually match types. This is the fastest method but isn't type-safe.
24
24
25
25
1. Use the type-safe statically linked library functions in TCHAR.H. To do so, define the constant **_NO_INLINING** on the command line. This is the slowest method, but the most type-safe.
0 commit comments