/* * debug.c * * Copyright (C) 2004 - 2016 Vladislav Bolkhovitin * Copyright (C) 2004 - 2005 Leonid Stoljar * Copyright (C) 2007 - 2016 SanDisk Corporation * * Contains helper functions for execution tracing and error reporting. * Intended to be included in main .c file. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, version 2 * of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #include #include #include #include #include #include #include "debug.h" pid_t gettid(void) { return syscall(__NR_gettid); } #if defined(DEBUG) || defined(TRACING) #define TRACE_BUF_SIZE 512 static char trace_buf[TRACE_BUF_SIZE]; static pthread_spinlock_t trace_buf_lock; int debug_print_prefix(unsigned long trace_flag, const char *prefix, const char *func, int line) { int i = 0; pthread_spin_lock(&trace_buf_lock); if (trace_flag & TRACE_TIME) { struct tm t; time_t tt; time(&tt); localtime_r(&tt, &t); i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%d:%d:%d ", t.tm_hour, t.tm_min, t.tm_sec); } if (trace_flag & TRACE_PID) i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "[%d]: ", gettid()); if (prefix != NULL) i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%s:", prefix); if (trace_flag & TRACE_FUNCTION) i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%s:", func); if (trace_flag & TRACE_LINE) i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%i:", line); if (i > 0) PRINTN(LOG_INFO, "%s", trace_buf); pthread_spin_unlock(&trace_buf_lock); return i; } void debug_print_buffer(const void *data, int len) { int z, z1, i; const unsigned char *buf = (const unsigned char *) data; int f = 0; if (buf == NULL) return; pthread_spin_lock(&trace_buf_lock); PRINT(LOG_INFO, " (h)___0__1__2__3__4__5__6__7__8__9__A__B__C__D__E__F"); for (z = 0, z1 = 0, i = 0; z < len; z++) { if (z % 16 == 0) { if (z != 0) { i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, " "); for (; (z1 < z) && (i < TRACE_BUF_SIZE - 1); z1++) { if ((buf[z1] >= 0x20) && (buf[z1] < 0x80)) trace_buf[i++] = buf[z1]; else trace_buf[i++] = '.'; } trace_buf[i] = '\0'; PRINT(LOG_INFO, "%s", trace_buf); i = 0; f = 1; } i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%4x: ", z); } i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, "%02x ", buf[z]); } i += snprintf(&trace_buf[i], TRACE_BUF_SIZE - i, " "); for (; (z1 < z) && (i < TRACE_BUF_SIZE - 1); z1++) { if ((buf[z1] > 0x20) && (buf[z1] < 0x80)) trace_buf[i++] = buf[z1]; else trace_buf[i++] = '.'; } trace_buf[i] = '\0'; if (f) PRINT(LOG_INFO, "%s", trace_buf); else PRINT(LOG_INFO, "%s", trace_buf); pthread_spin_unlock(&trace_buf_lock); } int debug_init(void) { int res; res = pthread_spin_init(&trace_buf_lock, PTHREAD_PROCESS_PRIVATE); if (res != 0) { res = errno; PRINT_ERROR("pthread_spin_init() failed: %s", strerror(res)); } return res; } void debug_done(void) { pthread_spin_destroy(&trace_buf_lock); } #endif /* DEBUG || TRACING */