|
Packit Service |
20376f |
#include "clar_libgit2.h"
|
|
Packit Service |
20376f |
#include "clar_libgit2_trace.h"
|
|
Packit Service |
20376f |
#include "clar_libgit2_timer.h"
|
|
Packit Service |
20376f |
#include "trace.h"
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
struct method {
|
|
Packit Service |
20376f |
const char *name;
|
|
Packit Service |
20376f |
void (*git_trace_cb)(git_trace_level_t level, const char *msg);
|
|
Packit Service |
20376f |
void (*close)(void);
|
|
Packit Service |
20376f |
};
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#if defined(GIT_TRACE)
|
|
Packit Service |
20376f |
static void _git_trace_cb__printf(git_trace_level_t level, const char *msg)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
/* TODO Use level to print a per-message prefix. */
|
|
Packit Service |
20376f |
GIT_UNUSED(level);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
printf("%s\n", msg);
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#if defined(GIT_WIN32)
|
|
Packit Service |
20376f |
static void _git_trace_cb__debug(git_trace_level_t level, const char *msg)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
/* TODO Use level to print a per-message prefix. */
|
|
Packit Service |
20376f |
GIT_UNUSED(level);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
OutputDebugString(msg);
|
|
Packit Service |
20376f |
OutputDebugString("\n");
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
printf("%s\n", msg);
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
#else
|
|
Packit Service |
20376f |
#define _git_trace_cb__debug _git_trace_cb__printf
|
|
Packit Service |
20376f |
#endif
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
static void _trace_printf_close(void)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
fflush(stdout);
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#define _trace_debug_close _trace_printf_close
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
static struct method s_methods[] = {
|
|
Packit Service |
20376f |
{ "printf", _git_trace_cb__printf, _trace_printf_close },
|
|
Packit Service |
20376f |
{ "debug", _git_trace_cb__debug, _trace_debug_close },
|
|
Packit Service |
20376f |
/* TODO add file method */
|
|
Packit Service |
20376f |
{0},
|
|
Packit Service |
20376f |
};
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
static int s_trace_loaded = 0;
|
|
Packit Service |
20376f |
static int s_trace_level = GIT_TRACE_NONE;
|
|
Packit Service |
20376f |
static struct method *s_trace_method = NULL;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
static int set_method(const char *name)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
int k;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (!name || !*name)
|
|
Packit Service |
20376f |
name = "printf";
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
for (k=0; (s_methods[k].name); k++) {
|
|
Packit Service |
20376f |
if (strcmp(name, s_methods[k].name) == 0) {
|
|
Packit Service |
20376f |
s_trace_method = &s_methods[k];
|
|
Packit Service |
20376f |
return 0;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
fprintf(stderr, "Unknown CLAR_TRACE_METHOD: '%s'\n", name);
|
|
Packit Service |
20376f |
return -1;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Lookup CLAR_TRACE_LEVEL and CLAR_TRACE_METHOD from
|
|
Packit Service |
20376f |
* the environment and set the above s_trace_* fields.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* If CLAR_TRACE_LEVEL is not set, we disable tracing.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* TODO If set, we assume GIT_TRACE_TRACE level, which
|
|
Packit Service |
20376f |
* logs everything. Later, we may want to parse the
|
|
Packit Service |
20376f |
* value of the environment variable and set a specific
|
|
Packit Service |
20376f |
* level.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* We assume the "printf" method. This can be changed
|
|
Packit Service |
20376f |
* with the CLAR_TRACE_METHOD environment variable.
|
|
Packit Service |
20376f |
* Currently, this is only needed on Windows for a "debug"
|
|
Packit Service |
20376f |
* version which also writes to the debug output window
|
|
Packit Service |
20376f |
* in Visual Studio.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* TODO add a "file" method that would open and write
|
|
Packit Service |
20376f |
* to a well-known file. This would help keep trace
|
|
Packit Service |
20376f |
* output and clar output separate.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
static void _load_trace_params(void)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
char *sz_level;
|
|
Packit Service |
20376f |
char *sz_method;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
s_trace_loaded = 1;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
sz_level = cl_getenv("CLAR_TRACE_LEVEL");
|
|
Packit Service |
20376f |
if (!sz_level || !*sz_level) {
|
|
Packit Service |
20376f |
s_trace_level = GIT_TRACE_NONE;
|
|
Packit Service |
20376f |
s_trace_method = NULL;
|
|
Packit Service |
20376f |
return;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/* TODO Parse sz_level and set s_trace_level. */
|
|
Packit Service |
20376f |
s_trace_level = GIT_TRACE_TRACE;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
sz_method = cl_getenv("CLAR_TRACE_METHOD");
|
|
Packit Service |
20376f |
if (set_method(sz_method) < 0)
|
|
Packit Service |
20376f |
set_method(NULL);
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#define HR "================================================================"
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Timer to report the take spend in a test's run() method.
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
static cl_perf_timer s_timer_run = CL_PERF_TIMER_INIT;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Timer to report total time in a test (init, run, cleanup).
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
static cl_perf_timer s_timer_test = CL_PERF_TIMER_INIT;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
void _cl_trace_cb__event_handler(
|
|
Packit Service |
20376f |
cl_trace_event ev,
|
|
Packit Service |
20376f |
const char *suite_name,
|
|
Packit Service |
20376f |
const char *test_name,
|
|
Packit Service |
20376f |
void *payload)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
GIT_UNUSED(payload);
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
switch (ev) {
|
|
Packit Service |
20376f |
case CL_TRACE__SUITE_BEGIN:
|
|
Packit Service |
20376f |
git_trace(GIT_TRACE_TRACE, "\n\n%s\n%s: Begin Suite", HR, suite_name);
|
|
Packit Service |
20376f |
#if 0 && defined(GIT_MSVC_CRTDBG)
|
|
Packit Service |
20376f |
git_win32__crtdbg_stacktrace__dump(
|
|
Packit Service |
20376f |
GIT_WIN32__CRTDBG_STACKTRACE__SET_MARK,
|
|
Packit Service |
20376f |
suite_name);
|
|
Packit Service |
20376f |
#endif
|
|
Packit Service |
20376f |
break;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
case CL_TRACE__SUITE_END:
|
|
Packit Service |
20376f |
#if 0 && defined(GIT_MSVC_CRTDBG)
|
|
Packit Service |
20376f |
/* As an example of checkpointing, dump leaks within this suite.
|
|
Packit Service |
20376f |
* This may generate false positives for things like the global
|
|
Packit Service |
20376f |
* TLS error state and maybe the odb cache since they aren't
|
|
Packit Service |
20376f |
* freed until the global shutdown and outside the scope of this
|
|
Packit Service |
20376f |
* set of tests.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* This may under-report if the test itself uses a checkpoint.
|
|
Packit Service |
20376f |
* See tests/trace/windows/stacktrace.c
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
git_win32__crtdbg_stacktrace__dump(
|
|
Packit Service |
20376f |
GIT_WIN32__CRTDBG_STACKTRACE__LEAKS_SINCE_MARK,
|
|
Packit Service |
20376f |
suite_name);
|
|
Packit Service |
20376f |
#endif
|
|
Packit Service |
20376f |
git_trace(GIT_TRACE_TRACE, "\n\n%s: End Suite\n%s", suite_name, HR);
|
|
Packit Service |
20376f |
break;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
case CL_TRACE__TEST__BEGIN:
|
|
Packit Service |
20376f |
git_trace(GIT_TRACE_TRACE, "\n%s::%s: Begin Test", suite_name, test_name);
|
|
Packit Service |
20376f |
cl_perf_timer__init(&s_timer_test);
|
|
Packit Service |
20376f |
cl_perf_timer__start(&s_timer_test);
|
|
Packit Service |
20376f |
break;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
case CL_TRACE__TEST__END:
|
|
Packit Service |
20376f |
cl_perf_timer__stop(&s_timer_test);
|
|
Packit Service |
20376f |
git_trace(GIT_TRACE_TRACE, "%s::%s: End Test (%.3f %.3f)", suite_name, test_name,
|
|
Packit Service |
20376f |
cl_perf_timer__last(&s_timer_run),
|
|
Packit Service |
20376f |
cl_perf_timer__last(&s_timer_test));
|
|
Packit Service |
20376f |
break;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
case CL_TRACE__TEST__RUN_BEGIN:
|
|
Packit Service |
20376f |
git_trace(GIT_TRACE_TRACE, "%s::%s: Begin Run", suite_name, test_name);
|
|
Packit Service |
20376f |
cl_perf_timer__init(&s_timer_run);
|
|
Packit Service |
20376f |
cl_perf_timer__start(&s_timer_run);
|
|
Packit Service |
20376f |
break;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
case CL_TRACE__TEST__RUN_END:
|
|
Packit Service |
20376f |
cl_perf_timer__stop(&s_timer_run);
|
|
Packit Service |
20376f |
git_trace(GIT_TRACE_TRACE, "%s::%s: End Run", suite_name, test_name);
|
|
Packit Service |
20376f |
break;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
case CL_TRACE__TEST__LONGJMP:
|
|
Packit Service |
20376f |
cl_perf_timer__stop(&s_timer_run);
|
|
Packit Service |
20376f |
git_trace(GIT_TRACE_TRACE, "%s::%s: Aborted", suite_name, test_name);
|
|
Packit Service |
20376f |
break;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
default:
|
|
Packit Service |
20376f |
break;
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
#endif /*GIT_TRACE*/
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* Setup/Enable git_trace() based upon settings user's environment.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
void cl_global_trace_register(void)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
#if defined(GIT_TRACE)
|
|
Packit Service |
20376f |
if (!s_trace_loaded)
|
|
Packit Service |
20376f |
_load_trace_params();
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
if (s_trace_level == GIT_TRACE_NONE)
|
|
Packit Service |
20376f |
return;
|
|
Packit Service |
20376f |
if (s_trace_method == NULL)
|
|
Packit Service |
20376f |
return;
|
|
Packit Service |
20376f |
if (s_trace_method->git_trace_cb == NULL)
|
|
Packit Service |
20376f |
return;
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
git_trace_set(s_trace_level, s_trace_method->git_trace_cb);
|
|
Packit Service |
20376f |
cl_trace_register(_cl_trace_cb__event_handler, NULL);
|
|
Packit Service |
20376f |
#endif
|
|
Packit Service |
20376f |
}
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/**
|
|
Packit Service |
20376f |
* If we turned on git_trace() earlier, turn it off.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
* This is intended to let us close/flush any buffered
|
|
Packit Service |
20376f |
* IO if necessary.
|
|
Packit Service |
20376f |
*
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
void cl_global_trace_disable(void)
|
|
Packit Service |
20376f |
{
|
|
Packit Service |
20376f |
#if defined(GIT_TRACE)
|
|
Packit Service |
20376f |
cl_trace_register(NULL, NULL);
|
|
Packit Service |
20376f |
git_trace_set(GIT_TRACE_NONE, NULL);
|
|
Packit Service |
20376f |
if (s_trace_method && s_trace_method->close)
|
|
Packit Service |
20376f |
s_trace_method->close();
|
|
Packit Service |
20376f |
|
|
Packit Service |
20376f |
/* Leave s_trace_ vars set so they can restart tracing
|
|
Packit Service |
20376f |
* since we only want to hit the environment variables
|
|
Packit Service |
20376f |
* once.
|
|
Packit Service |
20376f |
*/
|
|
Packit Service |
20376f |
#endif
|
|
Packit Service |
20376f |
}
|