| #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 |
| } |