-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathREADME
184 lines (125 loc) · 4.74 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
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());
}
...
}