Skip to content

Commit e582656

Browse files
authored
Merge pull request #4783 from corob-msft/learn/corob/crt-debugging-move
Migrate CRT Debug docs from VS docs
2 parents 0f360e2 + 4122642 commit e582656

File tree

72 files changed

+945
-78
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+945
-78
lines changed

docs/build/tips-for-improving-time-critical-code.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ Instead of multiple heaps, you can use helper functions to interface between you
101101

102102
In some cases, however, using the default heap can reduce locality of reference. Use Process Viewer, Spy++, or Performance Monitor to measure the effects of moving objects from heap to heap.
103103

104-
Measure your heaps so you can account for every allocation on the heap. Use the C run-time [debug heap routines](/visualstudio/debugger/crt-debug-heap-details) to checkpoint and dump your heap. You can read the output into a spreadsheet program like Microsoft Excel and use pivot tables to view the results. Note the total number, size, and distribution of allocations. Compare these results with the size of working sets. Also look at the clustering of related-sized objects.
104+
Measure your heaps so you can account for every allocation on the heap. Use the C run-time [debug heap routines](../c-runtime-library/crt-debug-heap-details.md) to checkpoint and dump your heap. You can read the output into a spreadsheet program like Microsoft Excel and use pivot tables to view the results. Note the total number, size, and distribution of allocations. Compare these results with the size of working sets. Also look at the clustering of related-sized objects.
105105

106106
You can also use the performance counters to monitor memory usage.
107107

docs/c-runtime-library/control-flags.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ ms.assetid: 8dbd24a5-0633-42d1-9771-776db338465f
88
---
99
# Control flags
1010

11-
The debug version of the Microsoft C run-time library uses the following flags to control the heap allocation and reporting process. For more information, see [CRT debugging techniques](/visualstudio/debugger/crt-debugging-techniques).
11+
The debug version of the Microsoft C run-time library uses the following flags to control the heap allocation and reporting process. For more information, see [CRT debugging techniques](./crt-debugging-techniques.md).
1212

1313
| Flag | Description |
1414
|---|---|

docs/c-runtime-library/crt-debug-heap-details.md

Lines changed: 328 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
---
2+
title: CRT debugging techniques
3+
description: There are various techniques you can use to debug a program that uses the C run-time (CRT) library. Use this article and its links to learn about such techniques.
4+
ms.custom: SEO-VS-2020
5+
ms.date: 02/03/2023
6+
f1_keywords:
7+
- "c.runtime.debugging"
8+
helpviewer_keywords:
9+
- "debugging [CRT]"
10+
- "CRT, debugging"
11+
- "debugging [C++], CRT debug support"
12+
---
13+
# CRT debugging techniques
14+
15+
When you debug a program that uses the C run-time library, these debugging techniques might be useful.
16+
17+
## CRT debug library use
18+
19+
The C runtime (CRT) library provides extensive debugging support. To use one of the CRT debug libraries, you must link with [`/DEBUG`](/cpp/build/reference/debug-generate-debug-info) and compile with [`/MDd`, `/MTd`, or `/LDd`](../build/reference/md-mt-ld-use-run-time-library.md).
20+
21+
The main definitions and macros for CRT debugging can be found in the`<crtdbg.h>` header file.
22+
23+
The functions in the CRT debug libraries are compiled with debug information ([/Z7, /Zd, /Zi, /ZI (Debug Information Format)](../build/reference/z7-zi-zi-debug-information-format.md)) and without optimization. Some functions contain assertions to verify parameters that are passed to them, and source code is provided. With this source code, you can step into CRT functions to confirm that the functions are working as you expect and check for bad parameters or memory states. (Some CRT technology is proprietary and doesn't provide source code for exception handling, floating point, and a few other routines.)
24+
25+
For more information on the various run-time libraries you can use, see [C Run-Time Libraries](./crt-library-features.md).
26+
27+
## Macros for reporting
28+
29+
For debugging, you can use the `_RPTn` and `_RPTFn` macros, defined in`<crtdbg.h>`, to replace the use of `printf` statements. You don't need to enclose them in `#ifdef` directives, because they automatically disappear in your release build when `_DEBUG` isn't defined.
30+
31+
| Macro | Description |
32+
|---|---|
33+
| `_RPT0`, `_RPT1`, `_RPT2`, `_RPT3`, `_RPT4` | Outputs a message string and zero to four arguments. For `_RPT1` through `_RPT4`, the message string serves as a printf-style formatting string for the arguments. |
34+
| `_RPTF0`, `_RPTF1`, `_RPTF2`, `_RPTF3`, `_RPTF4` | Same as `_RPTn`, but these macros also output the file name and line number where the macro is located. |
35+
36+
Consider the following example:
37+
38+
```cpp
39+
#ifdef _DEBUG
40+
if ( someVar > MAX_SOMEVAR )
41+
printf( "OVERFLOW! In NameOfThisFunc( ),
42+
someVar=%d, otherVar=%d.\n",
43+
someVar, otherVar );
44+
#endif
45+
```
46+
47+
This code outputs the values of `someVar` and `otherVar` to `stdout`. You can use the following call to `_RPTF2` to report these same values and, additionally, the file name and line number:
48+
49+
```cpp
50+
if (someVar > MAX_SOMEVAR) _RPTF2(_CRT_WARN, "In NameOfThisFunc( ), someVar= %d, otherVar= %d\n", someVar, otherVar );
51+
```
52+
53+
Some applications may need debug reporting that the macros supplied with the C run-time library don't provide. For these cases, you can write a macro designed specifically to fit your own requirements. In one of your header files, for example, you could include code like the following to define a macro called `ALERT_IF2`:
54+
55+
```cpp
56+
#ifndef _DEBUG /* For RELEASE builds */
57+
#define ALERT_IF2(expr, msg, arg1, arg2) do {} while (0)
58+
#else /* For DEBUG builds */
59+
#define ALERT_IF2(expr, msg, arg1, arg2) \
60+
do { \
61+
if ((expr) && \
62+
(1 == _CrtDbgReport(_CRT_ERROR, \
63+
__FILE__, __LINE__, msg, arg1, arg2))) \
64+
_CrtDbgBreak( ); \
65+
} while (0)
66+
#endif
67+
```
68+
69+
One call to `ALERT_IF2` could do all the functions of the `printf` code:
70+
71+
```cpp
72+
ALERT_IF2(someVar > MAX_SOMEVAR, "OVERFLOW! In NameOfThisFunc( ),
73+
someVar=%d, otherVar=%d.\n", someVar, otherVar );
74+
```
75+
76+
You can easily change a custom macro to report more or less information to different destinations. This approach is useful as your debugging requirements evolve.
77+
78+
## Debug hook function writing
79+
80+
You can write several kinds of custom debug hook functions that allow you to insert your code into some predefined points inside the debugger's normal processing.
81+
82+
### Client block hook functions
83+
84+
If you want to validate or report the contents of the data stored in `_CLIENT_BLOCK` blocks, you can write a function specifically for this purpose. The function that you write must have a prototype similar to the following, as defined in`<crtdbg.h>`:
85+
86+
```cpp
87+
void YourClientDump(void *, size_t)
88+
```
89+
90+
In other words, your hook function should accept a `void` pointer to the beginning of the allocation block, together with a `size_t` type value indicating the size of the allocation, and return `void`. Otherwise, its contents are up to you.
91+
92+
Once you've installed your hook function using [_CrtSetDumpClient](./reference/crtsetdumpclient.md), it will be called every time a `_CLIENT_BLOCK` block is dumped. You can then use [_CrtReportBlockType](./reference/crtreportblocktype.md) to get information on the type or subtype of dumped blocks.
93+
94+
The pointer to your function that you pass to `_CrtSetDumpClient` is of type `_CRT_DUMP_CLIENT`, as defined in`<crtdbg.h>`:
95+
96+
```cpp
97+
typedef void (__cdecl *_CRT_DUMP_CLIENT)
98+
(void *, size_t);
99+
```
100+
101+
### Allocation hook functions
102+
103+
An allocation hook function, installed using [`_CrtSetAllocHook`](./reference/crtsetallochook.md), is called every time memory is allocated, reallocated, or freed. You can use this type of hook for many different purposes. Use it to test how an application handles insufficient memory situations, such as to examine allocation patterns, or log allocation information for later analysis.
104+
105+
> [!NOTE]
106+
> Be aware of the restriction about using C runtime library functions in an allocation hook function, described in [Allocation hooks and crt memory allocations](#allocation-hooks-and-crt-memory-allocations).
107+
108+
An allocation hook function should have a prototype like the following example:
109+
110+
```cpp
111+
int YourAllocHook(int nAllocType, void *pvData,
112+
size_t nSize, int nBlockUse, long lRequest,
113+
const unsigned char * szFileName, int nLine )
114+
```
115+
116+
The pointer that you pass to [`_CrtSetAllocHook`](./reference/crtsetallochook.md) is of type `_CRT_ALLOC_HOOK`, as defined in`<crtdbg.h>`:
117+
118+
```cpp
119+
typedef int (__cdecl * _CRT_ALLOC_HOOK)
120+
(int, void *, size_t, int, long, const unsigned char *, int);
121+
```
122+
123+
When the run-time library calls your hook, the *`nAllocType`* argument indicates what allocation operation is about to be made (`_HOOK_ALLOC`, `_HOOK_REALLOC`, or `_HOOK_FREE`). In a free or in a reallocation, `pvData` has a pointer to the user article of the block about to be freed. However for an allocation, this pointer is null, because the allocation hasn't occurred. The remaining arguments contain the size of the allocation, its block type, a sequential request number, and a pointer to the file name. If available, the arguments also include the line number in which the allocation was made. After the hook function performs whatever analysis and other tasks its author wants, it must return either `TRUE`, indicating that the allocation operation can continue, or `FALSE`, indicating that the operation should fail. A simple hook of this type might check the amount of memory allocated so far, and return `FALSE` if that amount exceeded a small limit. The application would then experience the kind of allocation errors that would normally occur only when available memory was low. More complex hooks might keep track of allocation patterns, analyze memory use, or report when specific situations occur.
124+
125+
### Allocation hooks and CRT memory allocations
126+
127+
An important restriction on allocation hook functions is that they must explicitly ignore `_CRT_BLOCK` blocks. These blocks are the memory allocations made internally by C run-time library functions if they make any calls to C run-time library functions that allocate internal memory. You can ignore `_CRT_BLOCK` blocks by including the following code at the beginning of your allocation hook function:
128+
129+
```cpp
130+
if ( nBlockUse == _CRT_BLOCK )
131+
return( TRUE );
132+
```
133+
134+
If your allocation hook doesn't ignore `_CRT_BLOCK` blocks, then any C run-time library function called in your hook can trap the program in an endless loop. For example, `printf` makes an internal allocation. If your hook code calls `printf`, then the resulting allocation will cause your hook to be called again, which will call `printf` again, and so on, until the stack overflows. If you need to report `_CRT_BLOCK` allocation operations, one way to circumvent this restriction is to use Windows API functions, rather than C run-time functions, for formatting and output. Because the Windows APIs don't use the C run-time library heap, they won't trap your allocation hook in an endless loop.
135+
136+
If you examine the run-time library source files, you'll see that the default allocation hook function, `_CrtDefaultAllocHook` (which simply returns `TRUE`), is located in a separate file of its own, *`debug_heap_hook.cpp`*. If you want your allocation hook to be called even for the allocations made by the run-time startup code that is executed before your application's `main` function, you can replace this default function with one of your own, instead of using [`_CrtSetAllocHook`](./reference/crtsetallochook.md).
137+
138+
### Report hook functions
139+
140+
A report hook function, installed using [`_CrtSetReportHook`](./reference/crtsetreporthook.md), is called every time [`_CrtDbgReport`](./reference/crtdbgreport-crtdbgreportw.md) generates a debug report. You can use it, among other things, for filtering reports to focus on specific types of allocations. A report hook function should have a prototype like this example:
141+
142+
```cpp
143+
int AppReportHook(int nRptType, char *szMsg, int *retVal);
144+
```
145+
146+
The pointer that you pass to `_CrtSetReportHook` is of type `_CRT_REPORT_HOOK`, as defined in `<crtdbg.h>`:
147+
148+
```cpp
149+
typedef int (__cdecl *_CRT_REPORT_HOOK)(int, char *, int *);
150+
```
151+
152+
When the run-time library calls your hook function, the *`nRptType`* argument contains the category of the report (`_CRT_WARN`, `_CRT_ERROR`, or `_CRT_ASSERT`), *`szMsg`* contains a pointer to a fully assembled report message string, and *`retVal`* specifies whether `_CrtDbgReport` should continue normal execution after generating the report or start the debugger. (A *`retVal`* value of zero continues execution, a value of 1 starts the debugger.)
153+
154+
If the hook handles the message in question completely, so that no further reporting is required, it should return `TRUE`. If it returns `FALSE`, `_CrtDbgReport` will report the message normally.
155+
156+
## In this section
157+
158+
- [Debug versions of heap allocation functions](./debug-versions-of-heap-allocation-functions.md)
159+
160+
Discusses the special Debug versions of the heap allocation functions, including: how the CRT maps calls, the benefits of calling them explicitly, how to avoid conversion, tracking the separate types of allocations in client blocks, and the results of not defining `_DEBUG`.
161+
162+
- [CRT debug heap details](./crt-debug-heap-details.md)
163+
164+
Describes memory management and the debug heap, the types of blocks on the debug heap, heap state reporting functions, and how to use the debug heap to track allocation requests.
165+
166+
- [Find memory leaks using the CRT library](./find-memory-leaks-using-the-crt-library.md)
167+
168+
Covers techniques for detecting and isolating memory leaks by using the debugger and the C Run-Time Library.
169+
170+
## See also
171+
172+
- [Debugging Native Code](/visualstudio/debugger/debugging-native-code.md)
173+
- [Debugger Security](/visualstudio/debugger/debugger-security.md)

docs/c-runtime-library/crt-library-features.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ If you're using the **`/clr`** compiler switch, your code will be linked with a
7474

7575
For more information on using the CRT with **`/clr`**, see [Mixed (Native and Managed) Assemblies](../dotnet/mixed-native-and-managed-assemblies.md).
7676

77-
To build a debug version of your application, the [`_DEBUG`](./debug.md) flag must be defined and the application must be linked with a debug version of one of these libraries. For more information about using the debug versions of the library files, see [CRT debugging techniques](/visualstudio/debugger/crt-debugging-techniques).
77+
To build a debug version of your application, the [`_DEBUG`](./debug.md) flag must be defined and the application must be linked with a debug version of one of these libraries. For more information about using the debug versions of the library files, see [CRT debugging techniques](./crt-debugging-techniques.md).
7878

7979
This version of the CRT isn't fully conformant with the C99 standard. In versions before Visual Studio 2019 version 16.8, the `<tgmath.h>` header isn't supported. In all versions, the `CX_LIMITED_RANGE` and `FP_CONTRACT` pragma macros aren't supported. Certain elements such as the meaning of parameter specifiers in standard IO functions use legacy interpretations by default. You can use **`/Zc`** compiler conformance options and specify linker options to control some aspects of library conformance.
8080

docs/c-runtime-library/crtdbg-map-alloc.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ ms.assetid: 435242b8-caea-4063-b765-4a608200312b
1010

1111
When the `_CRTDBG_MAP_ALLOC` flag is defined in the debug version of an application, the base versions of the heap functions are directly mapped to their debug versions. The flag is used in Crtdbg.h to do the mapping. This flag is only available when the [`_DEBUG`](./debug.md) flag has been defined in the application.
1212

13-
For more information about using the debug version versus the base version of a heap function, see [Using the debug version versus the base version](/visualstudio/debugger/debug-versions-of-heap-allocation-functions).
13+
For more information about using the debug version versus the base version of a heap function, see [Debug versions of heap allocation functions](./debug-versions-of-heap-allocation-functions.md).
1414

1515
## See also
1616

docs/c-runtime-library/crtdbgflag.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ ms.assetid: 9e7adb47-8ab9-4e19-81d5-e2f237979973
1010

1111
The **`_crtDbgFlag`** flag consists of five bit-fields that control how memory allocations on the debug version of the heap are tracked, verified, reported, and dumped. The bit fields of the flag are set using the [`_CrtSetDbgFlag`](./reference/crtsetdbgflag.md) function. This flag and its bit fields are declared in Crtdbg.h. This flag is only available when the [`_DEBUG`](./debug.md) flag has been defined in the application.
1212

13-
For more information about using this flag along with other debug functions, see [Heap state reporting functions](/visualstudio/debugger/crt-debug-heap-details).
13+
For more information about using this flag along with other debug functions, see [Heap state reporting functions](./crt-debug-heap-details.md#heap-state-reporting-functions).
1414

1515
## See also
1616

docs/c-runtime-library/debug-routines.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ The debug version of the C runtime library supplies many diagnostic services tha
2020

2121
## Debug versions of the C runtime library routines
2222

23-
To use these routines, the [`_DEBUG`](./debug.md) flag must be defined. All of these routines do nothing in a retail build of an application. For more information on how to use the new debug routines, see [CRT debugging techniques](/visualstudio/debugger/crt-debugging-techniques).
23+
To use these routines, the [`_DEBUG`](./debug.md) flag must be defined. All of these routines do nothing in a retail build of an application. For more information on how to use the new debug routines, see [CRT debugging techniques](./crt-debugging-techniques.md).
2424

2525
| Routine | Use |
2626
|--|--|
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
title: Debug versions of heap allocation functions
3+
description: Use debug versions of heap allocation functions in the C run-time library. These functions have the same names as the release versions with _dbg appended.
4+
ms.date: 02/03/2023
5+
helpviewer_keywords:
6+
- "_CRTDBG_MAP_ALLOC macro"
7+
- "debugging [CRT], heap allocation functions"
8+
- "debugging memory leaks, CRT debug library functions"
9+
- "malloc function"
10+
- "memory leaks, CRT debug library functions"
11+
- "heap allocation, debug"
12+
- "_malloc_dbg function"
13+
---
14+
# Debug versions of heap allocation functions
15+
16+
The C runtime (CRT) library contains special Debug versions of the heap allocation functions. These functions have the same names as the Release versions with `_dbg` appended to them. This article describes the differences between the Release version of a CRT function and the `_dbg` version, using `malloc` and `_malloc_dbg` as examples.
17+
18+
## Behavior in debug builds
19+
20+
When [`_DEBUG`](./debug.md) is defined, the CRT maps all [`malloc`](./reference/malloc.md) calls to [`_malloc_dbg`](./reference/malloc-dbg.md). Therefore, you don't need to rewrite your code using `_malloc_dbg` instead of `malloc` to receive the benefits while debugging.
21+
22+
You might want to call `_malloc_dbg` explicitly, however. Calling `_malloc_dbg` explicitly has some added benefits:
23+
24+
- Tracking `_CLIENT_BLOCK` type allocations.
25+
26+
- Storing the source file and line number where the allocation request occurred.
27+
28+
If you don't want to convert your `malloc` calls to `_malloc_dbg`, you can obtain the source file information by defining [`_CRTDBG_MAP_ALLOC`](./crtdbg-map-alloc.md), which causes the preprocessor to directly map all calls to `malloc` to `_malloc_dbg` instead of relying on a wrapper around `malloc`.
29+
30+
To track the separate types of allocations in client blocks, you must call `_malloc_dbg` directly and set the `blockType` parameter to `_CLIENT_BLOCK`.
31+
32+
## Behavior in non-debug builds
33+
34+
When `_DEBUG` isn't defined, calls to `malloc` aren't disturbed, calls to `_malloc_dbg` are resolved to `malloc`, the definition of [`_CRTDBG_MAP_ALLOC`](./crtdbg-map-alloc.md) is ignored, and source file information pertaining to the allocation request isn't provided. Because `malloc` doesn't have a block type parameter, requests for `_CLIENT_BLOCK` types are treated as standard allocations.
35+
36+
## See also
37+
38+
[CRT debugging techniques](./crt-debugging-techniques.md)

0 commit comments

Comments
 (0)