summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJeff Hostetler <jeffhostetler@me.com>2015-06-09 14:38:30 -0700
committerJeff Hostetler <jeffhost@microsoft.com>2015-06-29 16:39:11 -0400
commit93b42728952487941bc2b0b78a7f0080b7b3d600 (patch)
tree40acaef6813719257a32835e1b962832964ba713 /tests
parent4a0313bc4e9b20a55aa6d0922312f97df743df72 (diff)
downloadlibgit2-93b42728952487941bc2b0b78a7f0080b7b3d600.tar.gz
Include stacktrace summary in memory leak output.
Diffstat (limited to 'tests')
-rw-r--r--tests/clar_libgit2_trace.c19
-rw-r--r--tests/main.c19
-rw-r--r--tests/trace/windows/stacktrace.c151
3 files changed, 170 insertions, 19 deletions
diff --git a/tests/clar_libgit2_trace.c b/tests/clar_libgit2_trace.c
index ae582d1cb..aaeeb7810 100644
--- a/tests/clar_libgit2_trace.c
+++ b/tests/clar_libgit2_trace.c
@@ -142,9 +142,28 @@ void _cl_trace_cb__event_handler(
switch (ev) {
case CL_TRACE__SUITE_BEGIN:
git_trace(GIT_TRACE_TRACE, "\n\n%s\n%s: Begin Suite", HR, suite_name);
+#if 0 && defined(GIT_MSVC_CRTDBG)
+ git_win32__crtdbg_stacktrace__dump(
+ GIT_WIN32__CRTDBG_STACKTRACE__SET_MARK,
+ suite_name);
+#endif
break;
case CL_TRACE__SUITE_END:
+#if 0 && defined(GIT_MSVC_CRTDBG)
+ /* As an example of checkpointing, dump leaks within this suite.
+ * This may generate false positives for things like the global
+ * TLS error state and maybe the odb cache since they aren't
+ * freed until the global shutdown and outside the scope of this
+ * set of tests.
+ *
+ * This may under-report if the test itself uses a checkpoint.
+ * See tests/trace/windows/stacktrace.c
+ */
+ git_win32__crtdbg_stacktrace__dump(
+ GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK,
+ suite_name);
+#endif
git_trace(GIT_TRACE_TRACE, "\n\n%s: End Suite\n%s", suite_name, HR);
break;
diff --git a/tests/main.c b/tests/main.c
index 56326da1c..f67c8ffbc 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -1,10 +1,3 @@
-
-#if defined(GIT_MSVC_CRTDBG)
-/* Enable MSVC CRTDBG memory leak reporting. See src/util.h for details. */
-#include <stdlib.h>
-#include <crtdbg.h>
-#endif
-
#include "clar_libgit2.h"
#include "clar_libgit2_trace.h"
@@ -16,18 +9,6 @@ int main(int argc, char *argv[])
{
int res;
-#if defined(GIT_MSVC_CRTDBG)
- _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
-
- _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
- _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
- _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_FILE);
-
- _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
- _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
- _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
-#endif
-
clar_test_init(argc, argv);
git_libgit2_init();
diff --git a/tests/trace/windows/stacktrace.c b/tests/trace/windows/stacktrace.c
new file mode 100644
index 000000000..c00c1b774
--- /dev/null
+++ b/tests/trace/windows/stacktrace.c
@@ -0,0 +1,151 @@
+#include "clar_libgit2.h"
+#include "win32/w32_stack.h"
+
+#if defined(GIT_MSVC_CRTDBG)
+static void a(void)
+{
+ char buf[10000];
+
+ cl_assert(git_win32__stack(buf, sizeof(buf), 0, NULL, NULL) == 0);
+
+#if 0
+ fprintf(stderr, "Stacktrace from [%s:%d]:\n%s\n", __FILE__, __LINE__, buf);
+#endif
+}
+
+static void b(void)
+{
+ a();
+}
+
+static void c(void)
+{
+ b();
+}
+#endif
+
+void test_trace_windows_stacktrace__basic(void)
+{
+#if defined(GIT_MSVC_CRTDBG)
+ c();
+#endif
+}
+
+
+void test_trace_windows_stacktrace__leaks(void)
+{
+#if defined(GIT_MSVC_CRTDBG)
+ void * p1;
+ void * p2;
+ void * p3;
+ void * p4;
+ int before, after;
+ int leaks;
+ int error;
+
+ /* remember outstanding leaks due to set setup
+ * and set mark/checkpoint.
+ */
+ before = git_win32__crtdbg_stacktrace__dump(
+ GIT_WIN32__CRTDBG_STACKTRACE__QUIET |
+ GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_TOTAL |
+ GIT_WIN32__CRTDBG_STACKTRACE__SET_MARK,
+ NULL);
+
+ p1 = git__malloc(5);
+ leaks = git_win32__crtdbg_stacktrace__dump(
+ GIT_WIN32__CRTDBG_STACKTRACE__QUIET |
+ GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK,
+ "p1");
+ cl_assert((leaks == 1));
+
+ p2 = git__malloc(5);
+ leaks = git_win32__crtdbg_stacktrace__dump(
+ GIT_WIN32__CRTDBG_STACKTRACE__QUIET |
+ GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK,
+ "p1,p2");
+ cl_assert((leaks == 2));
+
+ p3 = git__malloc(5);
+ leaks = git_win32__crtdbg_stacktrace__dump(
+ GIT_WIN32__CRTDBG_STACKTRACE__QUIET |
+ GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK,
+ "p1,p2,p3");
+ cl_assert((leaks == 3));
+
+ git__free(p2);
+ leaks = git_win32__crtdbg_stacktrace__dump(
+ GIT_WIN32__CRTDBG_STACKTRACE__QUIET |
+ GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK,
+ "p1,p3");
+ cl_assert((leaks == 2));
+
+ /* move the mark. only new leaks should appear afterwards */
+ error = git_win32__crtdbg_stacktrace__dump(
+ GIT_WIN32__CRTDBG_STACKTRACE__SET_MARK,
+ NULL);
+ cl_assert((error == 0));
+
+ leaks = git_win32__crtdbg_stacktrace__dump(
+ GIT_WIN32__CRTDBG_STACKTRACE__QUIET |
+ GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK,
+ "not_p1,not_p3");
+ cl_assert((leaks == 0));
+
+ p4 = git__malloc(5);
+ leaks = git_win32__crtdbg_stacktrace__dump(
+ GIT_WIN32__CRTDBG_STACKTRACE__QUIET |
+ GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK,
+ "p4,not_p1,not_p3");
+ cl_assert((leaks == 1));
+
+ git__free(p1);
+ git__free(p3);
+ leaks = git_win32__crtdbg_stacktrace__dump(
+ GIT_WIN32__CRTDBG_STACKTRACE__QUIET |
+ GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK,
+ "p4");
+ cl_assert((leaks == 1));
+
+ git__free(p4);
+ leaks = git_win32__crtdbg_stacktrace__dump(
+ GIT_WIN32__CRTDBG_STACKTRACE__QUIET |
+ GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK,
+ "end");
+ cl_assert((leaks == 0));
+
+ /* confirm current absolute leaks count matches beginning value. */
+ after = git_win32__crtdbg_stacktrace__dump(
+ GIT_WIN32__CRTDBG_STACKTRACE__QUIET |
+ GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_TOTAL,
+ "total");
+ cl_assert((before == after));
+#endif
+}
+
+#if defined(GIT_MSVC_CRTDBG)
+static void aux_cb_alloc__1(unsigned int *aux_id)
+{
+ static unsigned int aux_counter = 0;
+
+ *aux_id = aux_counter++;
+}
+
+static void aux_cb_lookup__1(unsigned int aux_id, char *aux_msg, unsigned int aux_msg_len)
+{
+ p_snprintf(aux_msg, aux_msg_len, "\tQQ%08x\n", aux_id);
+}
+
+#endif
+
+void test_trace_windows_stacktrace__aux1(void)
+{
+#if defined(GIT_MSVC_CRTDBG)
+ git_win32__stack__set_aux_cb(aux_cb_alloc__1, aux_cb_lookup__1);
+ c();
+ c();
+ c();
+ c();
+ git_win32__stack__set_aux_cb(NULL, NULL);
+#endif
+}