]>
Commit | Line | Data |
---|---|---|
93b42728 JH |
1 | /* |
2 | * Copyright (C) the libgit2 contributors. All rights reserved. | |
3 | * | |
4 | * This file is part of libgit2, distributed under the GNU GPL v2 with | |
5 | * a Linking Exception. For full terms see the included COPYING file. | |
6 | */ | |
eae0bfdc PP |
7 | #ifndef INCLUDE_win32_w32_crtdbg_stacktrace_h__ |
8 | #define INCLUDE_win32_w32_crtdbg_stacktrace_h__ | |
9 | ||
10 | #include "common.h" | |
93b42728 JH |
11 | |
12 | #if defined(GIT_MSVC_CRTDBG) | |
13 | ||
eae0bfdc PP |
14 | #include <stdlib.h> |
15 | #include <crtdbg.h> | |
16 | ||
17 | #include "git2/errors.h" | |
18 | #include "strnlen.h" | |
19 | ||
ac3d33df JK |
20 | /* MSVC CRTDBG memory leak reporting. |
21 | * | |
22 | * We DO NOT use the "_CRTDBG_MAP_ALLOC" macro described in the MSVC | |
23 | * documentation because all allocs/frees in libgit2 already go through | |
24 | * the "git__" routines defined in this file. Simply using the normal | |
25 | * reporting mechanism causes all leaks to be attributed to a routine | |
26 | * here in util.h (ie, the actual call to calloc()) rather than the | |
27 | * caller of git__calloc(). | |
28 | * | |
29 | * Therefore, we declare a set of "git__crtdbg__" routines to replace | |
30 | * the corresponding "git__" routines and re-define the "git__" symbols | |
31 | * as macros. This allows us to get and report the file:line info of | |
32 | * the real caller. | |
33 | * | |
34 | * We DO NOT replace the "git__free" routine because it needs to remain | |
35 | * a function pointer because it is used as a function argument when | |
36 | * setting up various structure "destructors". | |
37 | * | |
38 | * We also DO NOT use the "_CRTDBG_MAP_ALLOC" macro because it causes | |
39 | * "free" to be remapped to "_free_dbg" and this causes problems for | |
40 | * structures which define a field named "free". | |
41 | * | |
42 | * Finally, CRTDBG must be explicitly enabled and configured at program | |
43 | * startup. See tests/main.c for an example. | |
44 | */ | |
45 | ||
46 | int git_win32_crtdbg_init_allocator(git_allocator *allocator); | |
47 | ||
93b42728 JH |
48 | /** |
49 | * Initialize our memory leak tracking and de-dup data structures. | |
50 | * This should ONLY be called by git_libgit2_init(). | |
51 | */ | |
52 | void git_win32__crtdbg_stacktrace_init(void); | |
53 | ||
54 | /** | |
55 | * Shutdown our memory leak tracking and dump summary data. | |
56 | * This should ONLY be called by git_libgit2_shutdown(). | |
57 | * | |
58 | * We explicitly call _CrtDumpMemoryLeaks() during here so | |
59 | * that we can compute summary data for the leaks. We print | |
60 | * the stacktrace of each unique leak. | |
61 | * | |
62 | * This cleanup does not happen if the app calls exit() | |
63 | * without calling the libgit2 shutdown code. | |
64 | * | |
65 | * This info we print here is independent of any automatic | |
66 | * reporting during exit() caused by _CRTDBG_LEAK_CHECK_DF. | |
67 | * Set it in your app if you also want traditional reporting. | |
68 | */ | |
69 | void git_win32__crtdbg_stacktrace_cleanup(void); | |
70 | ||
71 | /** | |
72 | * Checkpoint options. | |
73 | */ | |
74 | typedef enum git_win32__crtdbg_stacktrace_options { | |
75 | /** | |
76 | * Set checkpoint marker. | |
77 | */ | |
78 | GIT_WIN32__CRTDBG_STACKTRACE__SET_MARK = (1 << 0), | |
79 | ||
80 | /** | |
81 | * Dump leaks since last checkpoint marker. | |
82 | * May not be combined with __LEAKS_TOTAL. | |
83 | * | |
84 | * Note that this may generate false positives for global TLS | |
85 | * error state and other global caches that aren't cleaned up | |
86 | * until the thread/process terminates. So when using this | |
87 | * around a region of interest, also check the final (at exit) | |
88 | * dump before digging into leaks reported here. | |
89 | */ | |
90 | GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK = (1 << 1), | |
91 | ||
92 | /** | |
93 | * Dump leaks since init. May not be combined | |
94 | * with __LEAKS_SINCE_MARK. | |
95 | */ | |
96 | GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_TOTAL = (1 << 2), | |
97 | ||
98 | /** | |
99 | * Suppress printing during dumps. | |
100 | * Just return leak count. | |
101 | */ | |
102 | GIT_WIN32__CRTDBG_STACKTRACE__QUIET = (1 << 3), | |
103 | ||
104 | } git_win32__crtdbg_stacktrace_options; | |
105 | ||
106 | /** | |
107 | * Checkpoint memory state and/or dump unique stack traces of | |
108 | * current memory leaks. | |
109 | * | |
110 | * @return number of unique leaks (relative to requested starting | |
111 | * point) or error. | |
112 | */ | |
113 | GIT_EXTERN(int) git_win32__crtdbg_stacktrace__dump( | |
114 | git_win32__crtdbg_stacktrace_options opt, | |
115 | const char *label); | |
116 | ||
117 | /** | |
118 | * Construct stacktrace and append it to the global buffer. | |
119 | * Return pointer to start of this string. On any error or | |
120 | * lack of buffer space, just return the given file buffer | |
121 | * so it will behave as usual. | |
122 | * | |
123 | * This should ONLY be called by our internal memory allocations | |
124 | * routines. | |
125 | */ | |
126 | const char *git_win32__crtdbg_stacktrace(int skip, const char *file); | |
127 | ||
128 | #endif | |
129 | #endif |