Created
November 4, 2012 13:15
-
-
Save attilammagyar/4011862 to your computer and use it in GitHub Desktop.
(C/C++) small helpers to generate debug logs in hairy situations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __DEBUG_H_INCLUDED | |
#define __DEBUG_H_INCLUDED | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/file.h> | |
#include <sys/time.h> | |
#include <libgen.h> | |
#include <time.h> | |
#include <errno.h> | |
#define __debug(msg, ...) do { \ | |
FILE* __f; \ | |
int __fd, __size, __rss, __peak; \ | |
int __errno; \ | |
char __errstr[512]; \ | |
char __file[512]; \ | |
__errno = errno; \ | |
__debug_get_memory_usage(&__size, &__rss, &__peak); \ | |
__f = fopen("/tmp/__debug.txt", "a+"); \ | |
if (__f) { \ | |
__fd = fileno(__f); \ | |
if (-1 != flock(__fd, LOCK_EX)) { \ | |
strncpy(__file, __FILE__, sizeof(__file)); \ | |
strncpy(__errstr, "Unknown", sizeof(__errstr)); \ | |
strerror_r(__errno, __errstr, sizeof(__errstr)); \ | |
fprintf( \ | |
__f, \ | |
"%d %s:%d/%s():\t", \ | |
(int)time(NULL), \ | |
basename(__file), \ | |
__LINE__, \ | |
__FUNCTION__ \ | |
); \ | |
fprintf(__f, (msg), ##__VA_ARGS__); \ | |
fprintf(__f, \ | |
", vmsize=%d, vmrss=%d, vmpeak=%d, errno=%d, errstr=\"%s\"\n", \ | |
__size, \ | |
__rss, \ | |
__peak, \ | |
__errno, \ | |
__errstr \ | |
); \ | |
} \ | |
fclose(__f); \ | |
} \ | |
} while (0) | |
static inline const char * const | |
__debug_safe_string(const char * const str) | |
{ | |
return str ? str : "--(NULL)--"; | |
} | |
#define __debug_begin() __debug("BEGIN") | |
#define __debug_end() __debug("END") | |
#define __debug_stopwatch_start() do { \ | |
struct timeval __begin, __end; \ | |
struct timezone __tz; \ | |
const char * __custom_str; \ | |
__debug("Starting stopwatch", NULL); \ | |
gettimeofday(&__begin, &__tz); \ | |
#define __debug_stopwatch_stop(custom_str) \ | |
gettimeofday(&__end, &__tz); \ | |
__custom_str = (custom_str); \ | |
__debug("Stopping stopwatch, runtime=%lu us%s%s", \ | |
(__end.tv_sec - __begin.tv_sec) * 1000000 \ | |
+ __end.tv_usec - __begin.tv_usec, \ | |
__custom_str ? ", " : "", \ | |
__custom_str ? __custom_str : "", \ | |
NULL); \ | |
} while (0) | |
static inline int | |
__debug_extract_number(char *str) | |
{ | |
char* num = str; | |
char* end; | |
for (num = str; *num && (*num < '0' || *num > '9'); ++num); | |
for (end = num; *end && *end >= '0' && *end <= '9'; ++end); | |
*end = '\x00'; | |
return atoi(num); | |
} | |
static inline void | |
__debug_get_memory_usage(int* const size, int* const rss, int* const peak) | |
{ | |
char str[4096]; | |
FILE* f; | |
*size = *rss = *peak = -1; | |
f = fopen("/proc/self/status", "r"); | |
if (!f) { | |
return; | |
} | |
while ( | |
(*size == -1 || *rss == -1 || *peak == -1) | |
&& !feof(f) | |
&& fgets(str, sizeof(str), f) | |
) { | |
if (*size == -1 && 0 == strncmp("VmSize:", str, 7)) { | |
*size = __debug_extract_number(&str[7]); | |
} | |
else if (*rss == -1 && 0 == strncmp("VmRSS:", str, 6)) { | |
*rss = __debug_extract_number(&str[6]); | |
} | |
else if (*peak == -1 && 0 == strncmp("VmPeak:", str, 7)) { | |
*peak = __debug_extract_number(&str[7]); | |
} | |
} | |
fclose(f); | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment