Skip to content

Instantly share code, notes, and snippets.

@nivpgir
Created November 18, 2018 16:12
Show Gist options
  • Save nivpgir/c4122f061d8c5f3e8f2e26d2788f1997 to your computer and use it in GitHub Desktop.
Save nivpgir/c4122f061d8c5f3e8f2e26d2788f1997 to your computer and use it in GitHub Desktop.
useful macros and functions for debugging in C
#ifndef DEBUG_UTILS_C
#define DEBUG_UTILS_C
#ifdef DEBUG
#include <stdio.h>
#define precision_unfactor 10000000ull
/* diff 2 timespec structs easily, used in following macros.
* uses a trick which isn't in the c standard but it works in gcc
* overflows very easily, should be improved later.
*/
#define diff_timespec(start, stop) \
({ \
unsigned long long sec_diff = (stop).tv_sec - (start).tv_sec; \
unsigned long long nsec_diff = (stop).tv_nsec - (start).tv_nsec; \
if (sec_diff > 0) \
{ \
nsec_diff += sec_diff*1000000000ull; \
} \
nsec_diff; \
}) \
/* print an array given it's length, also format needs to
* be given to print the type correctly
*/
#define print_arr(arr, format, len) \
{ \
int i = 0; \
for(i=0;i<len;i++) \
{ \
printf(format " ", arr[i]); \
} \
printf("\n"); \
} \
/* a macro to be used in mock functions,
* prints the time it entered the function,
* prints the file, function and line it's in,
* then runs the commands in `cmd`, that's meant to be used only
* to do the minimal operation so the function can pretend to
* return correctly (or with an error...), but could theoreticall contain
* any commands and even scale to a full implementation (use with care).
* finally prints the exit time from the function.
* does not handle return values, those should be handled outside (it's
* too complicated to give it the conditions required for the return value,
* if it even needs to return one.
*/
#define mock_func_exec(cmds) \
{ \
struct timespec tstart={0,0}, tend={0,0}; \
clock_gettime(CLOCK_MONOTONIC, &tstart); \
printf("%lld | ENTERED: %s:%s:%d\n", \
diff_timespec(g_start_time, tstart) / \
precision_unfactor, \
__FILE__, __FUNCTION__, __LINE__); \
cmds; \
clock_gettime(CLOCK_MONOTONIC, &tend); \
printf("%lld | EXITED: %s:%s:%d\n", \
diff_timespec(g_start_time, tstart) / \
precision_unfactor, \
__FILE__, __FUNCTION__, __LINE__); \
}
/* like printf, but automatically adds a prefix of:
* "DEBUG:__func__, __LINE__"
*/
#define Dprintf(format,...) \
printf("DEBUG:%s:%d: ", __func__, __LINE__); \
printf(format, ##__VA_ARGS__);
#else // DEBUG.
// make all these defines disappear
#undef precision_unfactor
#define diff_timespec(start, stop) (void)0
#define print_arr(arr, format, len) (void)0
#define mock_func_exec(cmds) (void)0
#define Dprintf(format,...) (void)0
#endif // DEBUG
#endif // DEBUG_UTILS_C
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment