Mercurial > libpst
comparison src/debug.c @ 33:12cac756bc05 stable-0-5-5
enable -d option, but if not specified, don't generate a debug file
author | carl |
---|---|
date | Tue, 10 Jul 2007 20:23:55 -0700 |
parents | b88ceb81dba2 |
children | 07177825c91b |
comparison
equal
deleted
inserted
replaced
32:c03974357771 | 33:12cac756bc05 |
---|---|
10 #ifdef _WIN32 | 10 #ifdef _WIN32 |
11 # define vsnprintf _vsnprintf | 11 # define vsnprintf _vsnprintf |
12 #endif | 12 #endif |
13 | 13 |
14 struct _debug_item { | 14 struct _debug_item { |
15 int type; | 15 int type; |
16 char * function; | 16 char * function; |
17 unsigned int line; | 17 unsigned int line; |
18 char * file; | 18 char * file; |
19 char * text; | 19 char * text; |
20 struct _debug_item *next; | 20 struct _debug_item *next; |
21 } *item_head=NULL, *item_tail=NULL, *item_ptr=NULL, *info_ptr=NULL, *temp_list=NULL; | 21 } *item_head=NULL, *item_tail=NULL, *item_ptr=NULL, *info_ptr=NULL, *temp_list=NULL; |
22 | 22 |
23 | |
23 struct _debug_func { | 24 struct _debug_func { |
24 char * name; | 25 char * name; |
25 struct _debug_func *next; | 26 struct _debug_func *next; |
26 } *func_head=NULL, *func_ptr=NULL; | 27 } *func_head=NULL, *func_ptr=NULL; |
27 | 28 |
28 | 29 |
29 void _debug_init(char *fname); | 30 void _debug_init(char *fname); |
30 void _debug_msg_info (int line, char *file, int type); | 31 void _debug_msg_info (int line, char *file, int type); |
42 // will do a debug_write, then create a new record, and write the | 43 // will do a debug_write, then create a new record, and write the |
43 // text body directly to the file | 44 // text body directly to the file |
44 #define MAX_MESSAGE_SIZE 4096 | 45 #define MAX_MESSAGE_SIZE 4096 |
45 | 46 |
46 void _pst_debug(char *fmt, ...) { | 47 void _pst_debug(char *fmt, ...) { |
47 va_list ap; | 48 va_list ap; |
48 va_start(ap,fmt); | 49 va_start(ap,fmt); |
49 vfprintf(stderr, fmt, ap); | 50 vfprintf(stderr, fmt, ap); |
50 va_end(ap); | 51 va_end(ap); |
51 } | 52 } |
53 | |
52 | 54 |
53 #define NUM_COL 30 | 55 #define NUM_COL 30 |
54 void _pst_debug_hexdump(FILE *out, unsigned char *buf, size_t size, int col) { | 56 void _pst_debug_hexdump(FILE *out, unsigned char *buf, size_t size, int col) { |
55 int off = 0, toff; | 57 int off = 0, toff; |
56 int count = 0; | 58 int count = 0; |
57 | 59 |
58 if (col == -1) { | 60 if (!out) return; // no file |
59 col = NUM_COL; | 61 if (col == -1) col = NUM_COL; |
60 } | 62 fprintf(out, "\n"); |
61 fprintf(out, "\n"); | 63 while (off < size) { |
62 while (off < size) { | 64 fprintf(out, "%X\t:", off); |
63 fprintf(out, "%X\t:", off); | 65 toff = off; |
64 toff = off; | 66 while (count < col && off < size) { |
65 while (count < col && off < size) { | 67 fprintf(out, "%02hhx ", buf[off]); |
66 fprintf(out, "%02hhx ", buf[off]); | 68 off++; count++; |
67 off++; count++; | 69 } |
68 } | 70 off = toff; |
69 off = toff; | 71 while (count < col) { |
70 while (count < col) { | 72 // only happens at end of block to pad the text over to the text column |
71 // only happens at end of block to pad the text over to the text column | 73 fprintf(out, " "); |
72 fprintf(out, " "); | 74 count++; |
73 count++; | 75 } |
74 } | 76 count = 0; |
75 count = 0; | 77 fprintf(out, ":"); |
76 fprintf(out, ":"); | 78 while (count < col && off < size) { |
77 while (count < col && off < size) { | 79 fprintf(out, "%c", isgraph(buf[off])?buf[off]:'.'); |
78 fprintf(out, "%c", isgraph(buf[off])?buf[off]:'.'); | 80 off++; count ++; |
79 off++; count ++; | 81 } |
80 } | 82 |
81 | 83 fprintf(out, "\n"); |
82 fprintf(out, "\n"); | 84 count=0; |
83 count=0; | 85 } |
84 } | 86 |
85 | 87 fprintf(out, "\n"); |
86 fprintf(out, "\n"); | 88 } |
87 } | 89 |
88 | |
89 void _pst_debug_hexprint(char *data, int size) { | |
90 int i = 0; | |
91 while (i < size) { | |
92 fprintf(stderr, "%02hhX", data[i]); | |
93 i++; | |
94 } | |
95 } | |
96 | 90 |
97 FILE *debug_fp = NULL; | 91 FILE *debug_fp = NULL; |
98 unsigned int max_items=DEBUG_MAX_ITEMS, curr_items=0; | 92 unsigned int max_items=DEBUG_MAX_ITEMS, curr_items=0; |
99 | 93 |
94 | |
100 void _debug_init(char* fname) { | 95 void _debug_init(char* fname) { |
101 unsigned char version = DEBUG_VERSION; | 96 unsigned char version = DEBUG_VERSION; |
102 item_head = item_tail = NULL; | 97 item_head = item_tail = NULL; |
103 curr_items = 0; | 98 curr_items = 0; |
104 if (debug_fp != NULL) | 99 if (debug_fp) _debug_close(); |
105 _debug_close(); | 100 if (!fname) return; |
106 if ((debug_fp = fopen(fname, "wb")) == NULL) { | 101 if ((debug_fp = fopen(fname, "wb")) == NULL) { |
107 fprintf(stderr, "Opening of file %s failed\n", fname); | 102 fprintf(stderr, "Opening of file %s failed\n", fname); |
108 exit(1); | 103 exit(1); |
109 } | 104 } |
110 fwrite(&version, 1, sizeof(char), debug_fp); | 105 fwrite(&version, 1, sizeof(char), debug_fp); |
111 } | 106 } |
107 | |
112 | 108 |
113 // function must be called before _debug_msg. It sets up the | 109 // function must be called before _debug_msg. It sets up the |
114 // structure for the function that follows | 110 // structure for the function that follows |
115 void _debug_msg_info(int line, char* file, int type) { | 111 void _debug_msg_info(int line, char* file, int type) { |
116 char *x; | 112 char *x; |
117 if (debug_fp == NULL) { | 113 if (!debug_fp) return; // no file |
118 fprintf(stderr, "debug_fp is NULL\n"); | 114 info_ptr = (struct _debug_item*) xmalloc(sizeof(struct _debug_item)); |
119 return; | 115 info_ptr->type = type; |
120 } | 116 info_ptr->line = line; |
121 info_ptr = (struct _debug_item*) xmalloc(sizeof(struct _debug_item)); | 117 x = (func_head==NULL?"No Function":func_head->name); |
122 info_ptr->type = type; | 118 info_ptr->function = (char*) xmalloc(strlen(x)+1); |
123 info_ptr->line = line; | 119 strcpy(info_ptr->function, x); |
124 x = (func_head==NULL?"No Function":func_head->name); | 120 |
125 info_ptr->function = (char*) xmalloc(strlen(x)+1); | 121 info_ptr->file = (char*) xmalloc(strlen(file)+1); |
126 strcpy(info_ptr->function, x); | 122 strcpy(info_ptr->file, file); |
127 | 123 |
128 info_ptr->file = (char*) xmalloc(strlen(file)+1); | 124 //put the current record on a temp linked list |
129 strcpy(info_ptr->file, file); | 125 info_ptr->next = temp_list; |
130 | 126 temp_list = info_ptr; |
131 //put the current record on a temp linked list | 127 } |
132 info_ptr->next = temp_list; | 128 |
133 temp_list = info_ptr; | |
134 } | |
135 | 129 |
136 void _debug_msg_text(char* fmt, ...) { | 130 void _debug_msg_text(char* fmt, ...) { |
137 va_list ap; | 131 va_list ap; |
138 int f, g; | 132 int f, g; |
139 char x[2]; | 133 char x[2]; |
140 struct _debug_item *temp; | 134 struct _debug_item *temp; |
141 if (debug_fp == NULL) | 135 if (!debug_fp) return; // no file |
142 return; | 136 va_start(ap, fmt); |
143 va_start(ap, fmt); | 137 // get the record off of the temp_list |
144 // get the record off of the temp_list | 138 info_ptr = temp_list; |
145 info_ptr = temp_list; | 139 if (info_ptr) |
146 if (info_ptr != NULL) | 140 temp_list = info_ptr->next; |
147 temp_list = info_ptr->next; | 141 else { |
148 else { | 142 fprintf(stderr, "NULL info_ptr. ERROR!!\n"); |
149 fprintf(stderr, "NULL info_ptr. ERROR!!\n"); | 143 exit(-2); |
150 exit(-2); | 144 } |
151 } | 145 // according to glibc 2.1, this should return the req. number of bytes for |
152 // according to glibc 2.1, this should return the req. number of bytes for | 146 // the string |
153 // the string | 147 #ifdef _WIN32 |
154 #ifdef _WIN32 | 148 // vsnprintf trick doesn't work. must use function called _vscprintf |
155 // vsnprintf trick doesn't work. must use function called _vscprintf | 149 // cannot find much documentation about this on internet or anywhere. |
156 // cannot find much documentation about this on internet or anywhere. | 150 // I assume it isn't a standard function, but only in VisualC++ |
157 // I assume it isn't a standard function, but only in VisualC++ | 151 f = _vscprintf(fmt, ap); |
158 f = _vscprintf(fmt, ap); | 152 #else |
159 #else | 153 f = vsnprintf(x, 1, fmt, ap); |
160 f = vsnprintf(x, 1, fmt, ap); | 154 #endif |
161 #endif | 155 va_end(ap); // must be called after vsnprintf() |
162 va_end(ap); // must be called after vsnprintf() | 156 |
163 | 157 if (f > 0 && f < MAX_MESSAGE_SIZE) { |
164 if (f > 0 && f < MAX_MESSAGE_SIZE) { | 158 info_ptr->text = (char*) xmalloc(f+1); |
165 info_ptr->text = (char*) xmalloc(f+1); | 159 va_start(ap, fmt); |
166 va_start(ap, fmt); | 160 if ((g = vsnprintf(info_ptr->text, f, fmt, ap)) == -1) { |
167 if ((g = vsnprintf(info_ptr->text, f, fmt, ap)) == -1) { | 161 fprintf(stderr, "_debug_msg: Dieing! vsnprintf returned -1 for format \"%s\"\n", fmt); |
168 fprintf(stderr, "_debug_msg: Dieing! vsnprintf returned -1 for format \"%s\"\n", fmt); | 162 exit(-2); |
169 exit(-2); | 163 } |
170 } | 164 va_end(ap); |
171 va_end(ap); | 165 info_ptr->text[g] = '\0'; |
172 info_ptr->text[g] = '\0'; | 166 if (f != g) { |
173 if (f != g) { | 167 fprintf(stderr, "_debug_msg: f != g\n"); |
174 fprintf(stderr, "_debug_msg: f != g\n"); | 168 } |
175 } | 169 } else if (f > 0) { // it is over the max_message_size then |
176 } else if (f > 0) { // it is over the max_message_size then | 170 f += strlen(info_ptr->file)+strlen(info_ptr->function); |
177 f += strlen(info_ptr->file)+strlen(info_ptr->function); | 171 temp = info_ptr; |
178 temp = info_ptr; | 172 _debug_write(); // dump the current messages |
179 _debug_write(); // dump the current messages | 173 info_ptr = temp; |
180 info_ptr = temp; | 174 va_start(ap, fmt); |
181 va_start(ap, fmt); | 175 _debug_write_msg(info_ptr, fmt, &ap, f); |
182 _debug_write_msg(info_ptr, fmt, &ap, f); | 176 va_end(ap); |
183 va_end(ap); | 177 free(info_ptr->function); |
184 free(info_ptr->function); | 178 free(info_ptr->file); |
185 free(info_ptr->file); | 179 free(info_ptr); |
186 free(info_ptr); | 180 info_ptr = NULL; |
187 info_ptr = NULL; | 181 return; |
188 return; | 182 } else { |
189 } else { | 183 fprintf(stderr, "_debug_msg: error getting requested size of debug message\n"); |
190 fprintf(stderr, "_debug_msg: error getting requested size of debug message\n"); | 184 info_ptr->text = "ERROR Saving\n"; |
191 info_ptr->text = "ERROR Saving\n"; | 185 } |
192 } | 186 |
193 | 187 if (!item_head) |
194 if (item_head == NULL) | 188 item_head = info_ptr; |
195 item_head = info_ptr; | 189 |
196 | 190 info_ptr->next = NULL; |
197 info_ptr->next = NULL; | 191 if (item_tail) item_tail->next = info_ptr; |
198 if (item_tail != NULL) | 192 item_tail = info_ptr; |
199 item_tail->next = info_ptr; | 193 |
200 item_tail = info_ptr; | 194 if (++curr_items == max_items) { |
201 | 195 // here we will jump off and save the contents |
202 if (++curr_items == max_items) { | 196 _debug_write(); |
203 // here we will jump off and save the contents | 197 info_ptr = NULL; |
204 _debug_write(); | 198 } |
205 info_ptr = NULL; | 199 } |
206 } | 200 |
207 } | |
208 | 201 |
209 void _debug_hexdump(unsigned char *x, int y, int cols) { | 202 void _debug_hexdump(unsigned char *x, int y, int cols) { |
210 struct _debug_item *temp; | 203 struct _debug_item *temp; |
211 if (debug_fp == NULL) | 204 if (!debug_fp) return; // no file |
212 return; | 205 info_ptr = temp_list; |
213 info_ptr = temp_list; | 206 if (info_ptr) |
214 if (info_ptr != NULL) | 207 temp_list = info_ptr->next; |
215 temp_list = info_ptr->next; | 208 temp = info_ptr; |
216 temp = info_ptr; | 209 _debug_write(); |
217 _debug_write(); | 210 info_ptr = temp; |
218 info_ptr = temp; | 211 _debug_write_hex(info_ptr, x, y, cols); |
219 _debug_write_hex(info_ptr, x, y, cols); | 212 free(info_ptr->function); |
220 free(info_ptr->function); | 213 free(info_ptr->file); |
221 free(info_ptr->file); | 214 free(info_ptr); |
222 free(info_ptr); | 215 info_ptr = NULL; |
223 info_ptr = NULL; | 216 } |
224 } | 217 |
225 | 218 |
226 void _debug_func(char *function) { | 219 void _debug_func(char *function) { |
227 func_ptr = xmalloc (sizeof(struct _debug_func)); | 220 func_ptr = xmalloc (sizeof(struct _debug_func)); |
228 func_ptr->name = xmalloc(strlen(function)+1); | 221 func_ptr->name = xmalloc(strlen(function)+1); |
229 strcpy(func_ptr->name, function); | 222 strcpy(func_ptr->name, function); |
230 func_ptr->next = func_head; | 223 func_ptr->next = func_head; |
231 func_head = func_ptr; | 224 func_head = func_ptr; |
232 } | 225 } |
226 | |
233 | 227 |
234 void _debug_func_ret() { | 228 void _debug_func_ret() { |
235 //remove the head item | 229 //remove the head item |
236 func_ptr = func_head; | 230 func_ptr = func_head; |
237 if (func_head != NULL) { | 231 if (func_head) { |
238 func_head = func_head->next; | 232 func_head = func_head->next; |
239 free(func_ptr->name); | 233 free(func_ptr->name); |
240 free(func_ptr); | 234 free(func_ptr); |
241 } else { | 235 } else { |
242 DIE(("function list is empty!\n")); | 236 DIE(("function list is empty!\n")); |
243 } | 237 } |
244 } | 238 } |
239 | |
245 | 240 |
246 void _debug_close(void) { | 241 void _debug_close(void) { |
247 _debug_write(); | 242 _debug_write(); |
248 while (func_head != NULL) { | 243 while (func_head) { |
249 func_ptr = func_head; | 244 func_ptr = func_head; |
250 func_head = func_head->next; | 245 func_head = func_head->next; |
251 free(func_ptr->name); | 246 free(func_ptr->name); |
252 free(func_ptr); | 247 free(func_ptr); |
253 } | 248 } |
254 | 249 |
255 if (debug_fp != NULL) | 250 if (debug_fp) fclose(debug_fp); |
256 fclose(debug_fp); | 251 debug_fp = NULL; |
257 debug_fp = NULL; | 252 } |
258 | 253 |
259 if (func_head != NULL) | |
260 while (func_head != NULL) { | |
261 printf("function '%s' still on stack\n", func_head->name); | |
262 func_head = func_head->next; | |
263 } | |
264 } | |
265 | 254 |
266 void _debug_write() { | 255 void _debug_write() { |
267 size_t size, ptr, funcname, filename, text, end; | 256 size_t size, ptr, funcname, filename, text, end; |
268 char *buf = NULL, rec_type; | 257 char *buf = NULL, rec_type; |
269 long index_pos = ftell (debug_fp), file_pos = index_pos; | 258 if (!debug_fp) return; // no file |
270 // add 2. One for the pointer to the next index, | 259 long index_pos = ftell (debug_fp), file_pos = index_pos; |
271 // one for the count of this index | 260 // add 2. One for the pointer to the next index, |
272 int index_size = ((curr_items+2) * sizeof(int)); | 261 // one for the count of this index |
273 int *index; | 262 int index_size = ((curr_items+2) * sizeof(int)); |
274 int index_ptr = 0; | 263 int *index; |
275 struct _debug_file_rec_m mfile_rec; | 264 int index_ptr = 0; |
276 struct _debug_file_rec_l lfile_rec; | 265 struct _debug_file_rec_m mfile_rec; |
277 | 266 struct _debug_file_rec_l lfile_rec; |
278 if (curr_items == 0) | 267 |
279 // no items to write. | 268 if (curr_items == 0) return; // no items to write. |
280 return; | 269 |
281 index = (int*) xmalloc(index_size); | 270 index = (int*) xmalloc(index_size); |
282 file_pos += index_size; | 271 file_pos += index_size; |
283 // write the index first, we will re-write it later, but | 272 // write the index first, we will re-write it later, but |
284 // we want to allocate the space | 273 // we want to allocate the space |
285 fwrite(index, index_size, 1, debug_fp); | 274 fwrite(index, index_size, 1, debug_fp); |
286 index[index_ptr++] = curr_items; | 275 index[index_ptr++] = curr_items; |
287 | 276 |
288 item_ptr = item_head; | 277 item_ptr = item_head; |
289 while (item_ptr != NULL) { | 278 while (item_ptr) { |
290 file_pos = ftell(debug_fp); | 279 file_pos = ftell(debug_fp); |
291 index[index_ptr++] = file_pos; | 280 index[index_ptr++] = file_pos; |
292 size = strlen(item_ptr->function)+strlen(item_ptr->file)+ | 281 size = strlen(item_ptr->function)+strlen(item_ptr->file)+ |
293 strlen(item_ptr->text) + 3; //for the three \0s | 282 strlen(item_ptr->text) + 3; //for the three \0s |
294 if (buf) free(buf); | 283 if (buf) free(buf); |
295 buf = xmalloc(size+1); | 284 buf = xmalloc(size+1); |
296 ptr = 0; | 285 ptr = 0; |
297 funcname=ptr; | 286 funcname=ptr; |
298 ptr += sprintf(&(buf[ptr]), "%s", item_ptr->function)+1; | 287 ptr += sprintf(&(buf[ptr]), "%s", item_ptr->function)+1; |
299 filename=ptr; | 288 filename=ptr; |
300 ptr += sprintf(&(buf[ptr]), "%s", item_ptr->file)+1; | 289 ptr += sprintf(&(buf[ptr]), "%s", item_ptr->file)+1; |
301 text=ptr; | 290 text=ptr; |
302 ptr += sprintf(&(buf[ptr]), "%s", item_ptr->text)+1; | 291 ptr += sprintf(&(buf[ptr]), "%s", item_ptr->text)+1; |
303 end=ptr; | 292 end=ptr; |
304 if (end > USHRT_MAX) { // bigger than can be stored in a short | 293 if (end > USHRT_MAX) { // bigger than can be stored in a short |
305 rec_type = 'L'; | 294 rec_type = 'L'; |
306 fwrite(&rec_type, 1, sizeof(char), debug_fp); | 295 fwrite(&rec_type, 1, sizeof(char), debug_fp); |
307 lfile_rec.type = item_ptr->type; | 296 lfile_rec.type = item_ptr->type; |
308 lfile_rec.line = item_ptr->line; | 297 lfile_rec.line = item_ptr->line; |
309 lfile_rec.funcname = funcname; | 298 lfile_rec.funcname = funcname; |
310 lfile_rec.filename = filename; | 299 lfile_rec.filename = filename; |
311 lfile_rec.text = text; | 300 lfile_rec.text = text; |
312 lfile_rec.end = end; | 301 lfile_rec.end = end; |
313 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); | 302 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); |
314 } else { | 303 } else { |
315 rec_type = 'M'; | 304 rec_type = 'M'; |
316 fwrite(&rec_type, 1, sizeof(char), debug_fp); | 305 fwrite(&rec_type, 1, sizeof(char), debug_fp); |
317 mfile_rec.type = item_ptr->type; | 306 mfile_rec.type = item_ptr->type; |
318 mfile_rec.line = item_ptr->line; | 307 mfile_rec.line = item_ptr->line; |
319 mfile_rec.funcname = funcname; | 308 mfile_rec.funcname = funcname; |
320 mfile_rec.filename = filename; | 309 mfile_rec.filename = filename; |
321 mfile_rec.text = text; | 310 mfile_rec.text = text; |
322 mfile_rec.end = end; | 311 mfile_rec.end = end; |
323 fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp); | 312 fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp); |
324 } | 313 } |
325 fwrite(buf, 1, ptr, debug_fp); | 314 fwrite(buf, 1, ptr, debug_fp); |
326 if (buf) free(buf); buf = NULL; | 315 if (buf) free(buf); buf = NULL; |
327 item_head = item_ptr->next; | 316 item_head = item_ptr->next; |
328 free(item_ptr->function); | 317 free(item_ptr->function); |
329 free(item_ptr->file); | 318 free(item_ptr->file); |
330 free(item_ptr->text); | 319 free(item_ptr->text); |
331 free(item_ptr); | 320 free(item_ptr); |
332 item_ptr = item_head; | 321 item_ptr = item_head; |
333 } | 322 } |
334 curr_items = 0; | 323 curr_items = 0; |
335 index[index_ptr] = ftell(debug_fp); | 324 index[index_ptr] = ftell(debug_fp); |
336 | 325 |
337 // we should now have a complete index | 326 // we should now have a complete index |
338 fseek(debug_fp, index_pos, SEEK_SET); | 327 fseek(debug_fp, index_pos, SEEK_SET); |
339 fwrite(index, index_size, 1, debug_fp); | 328 fwrite(index, index_size, 1, debug_fp); |
340 fseek(debug_fp, 0, SEEK_END); | 329 fseek(debug_fp, 0, SEEK_END); |
341 item_ptr = item_head = item_tail = NULL; | 330 item_ptr = item_head = item_tail = NULL; |
342 free(index); | 331 free(index); |
343 if (buf) free(buf); buf = NULL; | 332 if (buf) free(buf); buf = NULL; |
344 } | 333 } |
334 | |
345 | 335 |
346 void _debug_write_msg(struct _debug_item *item, char *fmt, va_list *ap, int size) { | 336 void _debug_write_msg(struct _debug_item *item, char *fmt, va_list *ap, int size) { |
347 struct _debug_file_rec_l lfile_rec; | 337 struct _debug_file_rec_l lfile_rec; |
348 struct _debug_file_rec_m mfile_rec; | 338 struct _debug_file_rec_m mfile_rec; |
349 unsigned char rec_type; | 339 unsigned char rec_type; |
350 int index_size = 3 * sizeof(int); | 340 int index_size = 3 * sizeof(int); |
351 int *index = malloc(index_size); | 341 int *index = malloc(index_size); |
352 int index_pos, file_pos; | 342 int index_pos, file_pos; |
353 char zero='\0'; | 343 char zero='\0'; |
354 unsigned int end; | 344 unsigned int end; |
355 index[0] = 1; //only one item in this index | 345 if (!debug_fp) return; // no file |
356 index_pos = ftell(debug_fp); | 346 index[0] = 1; //only one item in this index |
357 fwrite(index, index_size, 1, debug_fp); | 347 index_pos = ftell(debug_fp); |
358 | 348 fwrite(index, index_size, 1, debug_fp); |
359 index[1] = ftell(debug_fp); | 349 |
360 | 350 index[1] = ftell(debug_fp); |
361 if (size > USHRT_MAX) { // bigger than can be stored in a short | 351 |
362 rec_type = 'L'; | 352 if (size > USHRT_MAX) { // bigger than can be stored in a short |
363 fwrite(&rec_type, 1, sizeof(char), debug_fp); | 353 rec_type = 'L'; |
364 lfile_rec.type = item->type; | 354 fwrite(&rec_type, 1, sizeof(char), debug_fp); |
365 lfile_rec.line = item->line; | 355 lfile_rec.type = item->type; |
366 lfile_rec.funcname = 0; | 356 lfile_rec.line = item->line; |
367 lfile_rec.filename = strlen(item->function)+1; | 357 lfile_rec.funcname = 0; |
368 lfile_rec.text = lfile_rec.filename+strlen(item->file)+1; | 358 lfile_rec.filename = strlen(item->function)+1; |
369 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); | 359 lfile_rec.text = lfile_rec.filename+strlen(item->file)+1; |
370 } else { | 360 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); |
371 rec_type = 'M'; | 361 } else { |
372 fwrite(&rec_type, 1, sizeof(char), debug_fp); | 362 rec_type = 'M'; |
373 mfile_rec.type = item->type; | 363 fwrite(&rec_type, 1, sizeof(char), debug_fp); |
374 mfile_rec.line = item->line; | 364 mfile_rec.type = item->type; |
375 mfile_rec.funcname = 0; | 365 mfile_rec.line = item->line; |
376 mfile_rec.filename = strlen(item->function)+1; | 366 mfile_rec.funcname = 0; |
377 mfile_rec.text = mfile_rec.filename+strlen(item->file)+1; | 367 mfile_rec.filename = strlen(item->function)+1; |
378 fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp); | 368 mfile_rec.text = mfile_rec.filename+strlen(item->file)+1; |
379 } | 369 fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp); |
380 file_pos = ftell(debug_fp); | 370 } |
381 fwrite(item->function, strlen(item->function)+1, 1, debug_fp); | 371 file_pos = ftell(debug_fp); |
382 fwrite(item->file, strlen(item->file)+1, 1, debug_fp); | 372 fwrite(item->function, strlen(item->function)+1, 1, debug_fp); |
383 vfprintf(debug_fp, fmt, *ap); | 373 fwrite(item->file, strlen(item->file)+1, 1, debug_fp); |
384 fwrite(&zero, 1, 1, debug_fp); | 374 vfprintf(debug_fp, fmt, *ap); |
385 | 375 fwrite(&zero, 1, 1, debug_fp); |
386 end = ftell(debug_fp)-file_pos; | 376 |
387 | 377 end = ftell(debug_fp)-file_pos; |
388 index[2] = ftell(debug_fp); | 378 |
389 fseek(debug_fp, index_pos, SEEK_SET); | 379 index[2] = ftell(debug_fp); |
390 fwrite(index, index_size, 1, debug_fp); | 380 fseek(debug_fp, index_pos, SEEK_SET); |
391 if (size > USHRT_MAX) { | 381 fwrite(index, index_size, 1, debug_fp); |
392 fwrite(&rec_type, 1, sizeof(char), debug_fp); | 382 if (size > USHRT_MAX) { |
393 lfile_rec.end = end; | 383 fwrite(&rec_type, 1, sizeof(char), debug_fp); |
394 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); | 384 lfile_rec.end = end; |
395 } else { | 385 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); |
396 fwrite(&rec_type, 1, sizeof(char), debug_fp); | 386 } else { |
397 mfile_rec.end = end; | 387 fwrite(&rec_type, 1, sizeof(char), debug_fp); |
398 fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp); | 388 mfile_rec.end = end; |
399 } | 389 fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp); |
400 fseek(debug_fp, 0, SEEK_END); | 390 } |
401 // that should do it... | 391 fseek(debug_fp, 0, SEEK_END); |
402 } | 392 // that should do it... |
393 } | |
394 | |
403 | 395 |
404 void _debug_write_hex(struct _debug_item *item, unsigned char *buf, int size, int col) { | 396 void _debug_write_hex(struct _debug_item *item, unsigned char *buf, int size, int col) { |
405 struct _debug_file_rec_l lfile_rec; | 397 struct _debug_file_rec_l lfile_rec; |
406 unsigned char rec_type; | 398 unsigned char rec_type; |
407 int index_size = 3 * sizeof(int); | 399 int index_size = 3 * sizeof(int); |
408 int *index = malloc(index_size); | 400 int *index = malloc(index_size); |
409 int index_pos, file_pos; | 401 int index_pos, file_pos; |
410 char zero='\0'; | 402 char zero='\0'; |
411 index[0] = 1; // only one item in this index run | 403 if (!debug_fp) return; // no file |
412 index_pos = ftell(debug_fp); | 404 index[0] = 1; // only one item in this index run |
413 fwrite(index, index_size, 1, debug_fp); | 405 index_pos = ftell(debug_fp); |
414 index[1] = ftell(debug_fp); | 406 fwrite(index, index_size, 1, debug_fp); |
415 | 407 index[1] = ftell(debug_fp); |
416 // always use the long | 408 |
417 rec_type = 'L'; | 409 // always use the long |
418 fwrite(&rec_type, 1, sizeof(char), debug_fp); | 410 rec_type = 'L'; |
419 lfile_rec.type = item->type; | 411 fwrite(&rec_type, 1, sizeof(char), debug_fp); |
420 lfile_rec.line = item->line; | 412 lfile_rec.type = item->type; |
421 lfile_rec.funcname = 0; | 413 lfile_rec.line = item->line; |
422 lfile_rec.filename = strlen(item->function)+1; | 414 lfile_rec.funcname = 0; |
423 lfile_rec.text = lfile_rec.filename+strlen(item->file)+1; | 415 lfile_rec.filename = strlen(item->function)+1; |
424 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); | 416 lfile_rec.text = lfile_rec.filename+strlen(item->file)+1; |
425 | 417 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); |
426 file_pos = ftell(debug_fp); | 418 |
427 fwrite(item->function, strlen(item->function)+1, 1, debug_fp); | 419 file_pos = ftell(debug_fp); |
428 fwrite(item->file, strlen(item->file)+1, 1, debug_fp); | 420 fwrite(item->function, strlen(item->function)+1, 1, debug_fp); |
429 | 421 fwrite(item->file, strlen(item->file)+1, 1, debug_fp); |
430 _pst_debug_hexdump(debug_fp, buf, size, col); | 422 |
431 fwrite(&zero, 1, 1, debug_fp); | 423 _pst_debug_hexdump(debug_fp, buf, size, col); |
432 lfile_rec.end = ftell(debug_fp)-file_pos; | 424 fwrite(&zero, 1, 1, debug_fp); |
433 | 425 lfile_rec.end = ftell(debug_fp)-file_pos; |
434 index[2] = ftell(debug_fp); | 426 |
435 fseek(debug_fp, index_pos, SEEK_SET); | 427 index[2] = ftell(debug_fp); |
436 fwrite(index, index_size, 1, debug_fp); | 428 fseek(debug_fp, index_pos, SEEK_SET); |
437 fwrite(&rec_type, 1, sizeof(char), debug_fp); | 429 fwrite(index, index_size, 1, debug_fp); |
438 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); | 430 fwrite(&rec_type, 1, sizeof(char), debug_fp); |
439 fseek(debug_fp, 0, SEEK_END); | 431 fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); |
440 } | 432 fseek(debug_fp, 0, SEEK_END); |
441 | 433 } |
434 | |
435 | |
442 void * xmalloc(size_t size) { | 436 void * xmalloc(size_t size) { |
443 void *mem = malloc(size); | 437 void *mem = malloc(size); |
444 if (mem == NULL) { | 438 if (!mem) { |
445 fprintf(stderr, "xMalloc: Out Of memory [req: %ld]\n", (long)size); | 439 fprintf(stderr, "xMalloc: Out Of memory [req: %ld]\n", (long)size); |
446 exit(1); | 440 exit(1); |
447 } | 441 } |
448 return mem; | 442 return mem; |
449 } | 443 } |
450 | 444 |