stacktrace.c 3.51 KB
Newer Older
1
#include "clar_libgit2.h"
2
#include "win32/w32_leakcheck.h"
3

4
#if defined(GIT_WIN32_LEAKCHECK)
5 6 7 8
static void a(void)
{
	char buf[10000];

9
	cl_assert(git_win32_leakcheck_stack(buf, sizeof(buf), 0, NULL, NULL) == 0);
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

#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)
{
29
#if defined(GIT_WIN32_LEAKCHECK)
30 31 32 33 34 35 36
	c();
#endif
}


void test_trace_windows_stacktrace__leaks(void)
{
37
#if defined(GIT_WIN32_LEAKCHECK)
38 39 40 41 42 43 44 45 46 47 48
	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.
	 */
49 50 51 52
	before = git_win32_leakcheck_stacktrace_dump(
		GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET |
		GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_TOTAL |
		GIT_WIN32_LEAKCHECK_STACKTRACE_SET_MARK,
53 54 55
		NULL);

	p1 = git__malloc(5);
56 57 58
	leaks = git_win32_leakcheck_stacktrace_dump(
		GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET |
		GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK,
59
		"p1");
60
	cl_assert_equal_i(1, leaks);
61 62

	p2 = git__malloc(5);
63 64 65
	leaks = git_win32_leakcheck_stacktrace_dump(
		GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET |
		GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK,
66
		"p1,p2");
67
	cl_assert_equal_i(2, leaks);
68 69

	p3 = git__malloc(5);
70 71 72
	leaks = git_win32_leakcheck_stacktrace_dump(
		GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET |
		GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK,
73
		"p1,p2,p3");
74
	cl_assert_equal_i(3, leaks);
75 76

	git__free(p2);
77 78 79
	leaks = git_win32_leakcheck_stacktrace_dump(
		GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET |
		GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK,
80
		"p1,p3");
81
	cl_assert_equal_i(2, leaks);
82 83

	/* move the mark. only new leaks should appear afterwards */
84 85
	error = git_win32_leakcheck_stacktrace_dump(
		GIT_WIN32_LEAKCHECK_STACKTRACE_SET_MARK,
86
		NULL);
87 88
	/* cannot use cl_git_pass() since that may allocate memory. */
	cl_assert_equal_i(0, error);
89

90 91 92
	leaks = git_win32_leakcheck_stacktrace_dump(
		GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET |
		GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK,
93
		"not_p1,not_p3");
94
	cl_assert_equal_i(0, leaks);
95 96

	p4 = git__malloc(5);
97 98 99
	leaks = git_win32_leakcheck_stacktrace_dump(
		GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET |
		GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK,
100
		"p4,not_p1,not_p3");
101
	cl_assert_equal_i(1, leaks);
102 103 104

	git__free(p1);
	git__free(p3);
105 106 107
	leaks = git_win32_leakcheck_stacktrace_dump(
		GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET |
		GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK,
108
		"p4");
109
	cl_assert_equal_i(1, leaks);
110 111

	git__free(p4);
112 113 114
	leaks = git_win32_leakcheck_stacktrace_dump(
		GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET |
		GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_SINCE_MARK,
115
		"end");
116
	cl_assert_equal_i(0, leaks);
117 118

	/* confirm current absolute leaks count matches beginning value. */
119 120 121
	after = git_win32_leakcheck_stacktrace_dump(
		GIT_WIN32_LEAKCHECK_STACKTRACE_QUIET |
		GIT_WIN32_LEAKCHECK_STACKTRACE_LEAKS_TOTAL,
122
		"total");
123
	cl_assert_equal_i(before, after);
124 125 126
#endif
}

127
#if defined(GIT_WIN32_LEAKCHECK)
128 129 130 131 132 133 134
static void aux_cb_alloc__1(unsigned int *aux_id)
{
	static unsigned int aux_counter = 0;

	*aux_id = aux_counter++;
}

135
static void aux_cb_lookup__1(unsigned int aux_id, char *aux_msg, size_t aux_msg_len)
136 137 138 139 140 141 142 143
{
	p_snprintf(aux_msg, aux_msg_len, "\tQQ%08x\n", aux_id);
}

#endif

void test_trace_windows_stacktrace__aux1(void)
{
144
#if defined(GIT_WIN32_LEAKCHECK)
145
	git_win32_leakcheck_stack_set_aux_cb(aux_cb_alloc__1, aux_cb_lookup__1);
146 147 148 149
	c();
	c();
	c();
	c();
150
	git_win32_leakcheck_stack_set_aux_cb(NULL, NULL);
151 152
#endif
}