LibDebug
Folders and files
Name | Name | Last commit date | ||
---|---|---|---|---|
parent directory.. | ||||
I. Init ======= Call DBG_INIT or DBG_INIT_EX at startup. If not called: - Log fd defaulted to stderr - Log level defaulted to DBG_LEVEL_DEFAULT (see Debug.h) TIP#1: You can adjust extra features by setting flags parameter to DBG_INIT_EX. See Debug.h for possible values. Examples: DBG_INIT("dirligo.log") DBG_INIT_EX(NULL, "debug3", -1) DBG_INIT_EX("dirligo.log", DBG_LEVEL_INFO, DBG_STATE_ENABLE) II. System error codes ====================== GetLastError() can be used: - Returns native GetLastError() on Windows. - Returns errno value on Linux. No #ifdef needed. III. Tracing code ================= Use DBG_ENTER or DBG_ENTER_EX to mark begin of function calls. Use DBG_LEAVE to mark end of function calls. TIP#1: DBG_ENTER2, DBG_ENTER3 etc. are enabled under DEBUG2, DEBUG3 levels only. Use them to avoid flooding log with a lot of enter/leaves messages if one of function is called very often. IV. Log levels ============== Defined in Debug.h. To set log level at init use DBG_INIT_EX at startup. To set log level after init use DBG_SET_LEVEL or DBG_INIT_EX with DBG_REINIT flag. Level name | Enabled macros =================+=================================================== DBG_LEVEL_NONE | Fatal quits without message -----------------+--------------------------------------------------- DBG_LEVEL_ERROR | Error, Fatal -----------------+--------------------------------------------------- DBG_LEVEL_INFO | DBG_INFO, DBG_HEAD -----------------+--------------------------------------------------- DBG_LEVEL_DEBUG1 | DEBUG1, DBG_MSG, DBG_MSG1, DBG_HEAD1, DBG_ENTER, | DBG_ENTER1, DBG_LEAVE, DBG_LEAVE1 -----------------+--------------------------------------------------- DBG_LEVEL_DEBUG2 | DEBUG2, DBG_MSG2, DBG_HEAD2, DBG_ENTER2, DBG_LEAVE2 -----------------+--------------------------------------------------- DBG_LEVEL_DEBUG3 | DEBUG3, DBG_MSG3, DBG_HEAD3 DBG_ENTER3, DBG_LEAVE3 -----------------+--------------------------------------------------- DBG_LEVEL_DEBUG4 | DEBUG4, DBG_MSG4, DBG_HEAD4 DBG_ENTER4, DBG_LEAVE4 -----------------+--------------------------------------------------- DBG_LEVEL_DEBUG5 | DEBUG5, DBG_MSG5, DBG_HEAD5 DBG_ENTER5, DBG_LEAVE5 | DBG_DUMP V. Monitoring process resources =============================== 1. To enable state monitor init log using DBG_INIT_EX with DBG_STATE_ENABLE flag. 2. To add/delete resources to monitor use DBG_SET_XXX marcos. DBG_SET_ADD - add object to monitor DBG_SET_DEL - remove object from monitor DBG_SET_MOVE - move object from one set to another (e.g. move mutex from locking to locked). Example: See example02-monitor. TIP#1: You can assign arbitar names to object ID to debug code easier. To do it see at: DBG_SET_ADD_EX - Add named object to monitor DBG_SET_RENAME - Rename anonymous object or change existing one VI. Monitoring I/O activity =========================== 1. To enable I/O logs use DBG_IO_ENABLE flag in DBG_INIT_EX. 2. I/O log is written to *.io.<pid>.log file. 3. To monitor I/O use DBG_IO_XXX macros: DBG_IO_WRITE_BEGIN(TYPE, ID, BUF, COUNT) DBG_IO_WRITE_END(TYPE, ID, BUF, COUNT) DBG_IO_READ_BEGIN(TYPE, ID, BUF, COUNT) DBG_IO_READ_END(TYPE, ID, BUF, COUNT) DBG_IO_CLOSE_BEGIN(TYPE, ID) DBG_IO_CLOSE_END(TYPE, ID) where TYPE is arbirtar string e.g. "socket". 4. Examples: // // Write some data to FD. // DBG_IO_WRITE_BEGIN("fd", fd, buf, count); written = write(fd, buf, count); DBG_IO_WRITE_END("fd", fd, buf, written); // // Read some data from socket. // DBG_IO_READ_BEGIN("socket", sock, buf, count); readed = recv(sock, buf, count, 0); DBG_IO_READ_END("fd", fd, buf, readed); // // Close stdio file. // DBG_IO_CLOSE_BEGIN("FILE*", f); fclose(f); DBG_IO_CLOSE_END("FILE*", f); See example04-io for full working code. VII. Catching errors ==================== You can use *FAIL* family macros: FAIL(X) - if X true jump to fail FAILEX(X, ...) - if X true write formatted messages at DBG_LEVEL_ERROR and jump to fail TIP#1: FAIL and FAILEX does NOT affect OS error code. You can catch it just after fail label. Example: { int exitCode = -1; ... FAIL(write(fd, buf, count) < 0); FAILEX(ptr == NULL, "ERROR: Ptr cannot be NULL."); ... // // Error handler. // exitCode = 0; fail: if (exitCode) { // // We fall here if function fail in middle. // Error("Fail with code : %d.\n", GetLastError()); } ... }