comparison src/debug.c @ 75:987aa872294e stable-0-6-11

Use ftello/fseeko to properly handle large files. Document and properly use datasize field in b5 blocks. Fix some MSVC compile issues and collect MSVC dependencies into one place.
author Carl Byington <carl@five-ten-sg.com>
date Tue, 03 Jun 2008 12:00:58 -0700
parents 3cb02cb1e6cd
children 56fa05fd5271
comparison
equal deleted inserted replaced
74:6f82d13e9300 75:987aa872294e
5 #include <stdlib.h> 5 #include <stdlib.h>
6 #include <stdarg.h> 6 #include <stdarg.h>
7 #include <ctype.h> 7 #include <ctype.h>
8 #include <string.h> 8 #include <string.h>
9 #include <limits.h> 9 #include <limits.h>
10
11 #ifdef _WIN32
12 # define vsnprintf _vsnprintf
13 #endif
14 10
15 struct pst_debug_item { 11 struct pst_debug_item {
16 int type; 12 int type;
17 char * function; 13 char * function;
18 unsigned int line; 14 unsigned int line;
127 123
128 void pst_debug_msg_text(const char* fmt, ...) { 124 void pst_debug_msg_text(const char* fmt, ...) {
129 va_list ap; 125 va_list ap;
130 int f, g; 126 int f, g;
131 char x[2]; 127 char x[2];
128 char *buf = NULL;
132 struct pst_debug_item *temp; 129 struct pst_debug_item *temp;
133 if (!debug_fp) return; // no file 130 if (!debug_fp) return; // no file
134 va_start(ap, fmt);
135 // get the record off of the temp_list 131 // get the record off of the temp_list
136 info_ptr = temp_list; 132 info_ptr = temp_list;
137 if (info_ptr) 133 if (info_ptr)
138 temp_list = info_ptr->next; 134 temp_list = info_ptr->next;
139 else { 135 else {
140 fprintf(stderr, "NULL info_ptr. ERROR!!\n"); 136 fprintf(stderr, "NULL info_ptr. ERROR!!\n");
141 exit(-2); 137 exit(-2);
142 } 138 }
143 // according to glibc 2.1, this should return the req. number of bytes for 139
144 // the string 140 #ifdef _WIN32
145 #ifdef _WIN32 141 // vsnprintf trick doesn't work on msvc.
146 // vsnprintf trick doesn't work. must use function called _vscprintf 142 g = 2000;
147 // cannot find much documentation about this on internet or anywhere. 143 f = -1;
148 // I assume it isn't a standard function, but only in VisualC++ 144 while (f < 0) {
149 f = _vscprintf(fmt, ap); 145 buf = realloc(buf, g+1);
150 #else 146 va_start(ap, fmt);
151 f = vsnprintf(x, 1, fmt, ap); 147 f = vsnprintf(buf, g, fmt, ap);
152 #endif 148 va_end(ap);
153 va_end(ap); // must be called after vsnprintf() 149 g += g/2;
150 }
151 free(buf);
152 #else
153 // according to glibc 2.1, this should return the req. number of bytes for
154 // the string
155 va_start(ap, fmt);
156 f = vsnprintf(x, 1, fmt, ap);
157 va_end(ap);
158 #endif
154 159
155 if (f > 0 && f < MAX_MESSAGE_SIZE) { 160 if (f > 0 && f < MAX_MESSAGE_SIZE) {
156 info_ptr->text = (char*) xmalloc(f+1); 161 info_ptr->text = (char*) xmalloc(f+1);
157 va_start(ap, fmt); 162 va_start(ap, fmt);
158 if ((g = vsnprintf(info_ptr->text, f, fmt, ap)) == -1) { 163 if ((g = vsnprintf(info_ptr->text, f, fmt, ap)) == -1) {
159 fprintf(stderr, "_debug_msg: Dieing! vsnprintf returned -1 for format \"%s\"\n", fmt); 164 fprintf(stderr, "_debug_msg: Dying! vsnprintf returned -1 for format \"%s\"\n", fmt);
160 exit(-2); 165 exit(-2);
161 } 166 }
162 va_end(ap); 167 va_end(ap);
163 info_ptr->text[g] = '\0'; 168 info_ptr->text[g] = '\0';
164 if (f != g) { 169 if (f != g) {
250 255
251 void pst_debug_write() { 256 void pst_debug_write() {
252 size_t size, ptr, funcname, filename, text, end; 257 size_t size, ptr, funcname, filename, text, end;
253 char *buf = NULL, rec_type; 258 char *buf = NULL, rec_type;
254 if (!debug_fp) return; // no file 259 if (!debug_fp) return; // no file
255 off_t index_pos = ftell(debug_fp); 260 off_t index_pos = ftello(debug_fp);
256 off_t file_pos = index_pos; 261 off_t file_pos = index_pos;
257 // add 2. One for the pointer to the next index, 262 // add 2. One for the pointer to the next index,
258 // one for the count of this index 263 // one for the count of this index
259 int index_size = ((curr_items+2) * sizeof(off_t)); 264 int index_size = ((curr_items+2) * sizeof(off_t));
260 off_t *index; 265 off_t *index;
272 pst_debug_fwrite(index, index_size, 1, debug_fp); 277 pst_debug_fwrite(index, index_size, 1, debug_fp);
273 index[index_ptr++] = curr_items; 278 index[index_ptr++] = curr_items;
274 279
275 item_ptr = item_head; 280 item_ptr = item_head;
276 while (item_ptr) { 281 while (item_ptr) {
277 file_pos = ftell(debug_fp); 282 file_pos = ftello(debug_fp);
278 index[index_ptr++] = file_pos; 283 index[index_ptr++] = file_pos;
279 size = strlen(item_ptr->function) + 284 size = strlen(item_ptr->function) +
280 strlen(item_ptr->file) + 285 strlen(item_ptr->file) +
281 strlen(item_ptr->text) + 3; //for the three \0s 286 strlen(item_ptr->text) + 3; //for the three \0s
282 if (buf) free(buf); 287 if (buf) free(buf);
318 free(item_ptr->text); 323 free(item_ptr->text);
319 free(item_ptr); 324 free(item_ptr);
320 item_ptr = item_head; 325 item_ptr = item_head;
321 } 326 }
322 curr_items = 0; 327 curr_items = 0;
323 index[index_ptr] = ftell(debug_fp); 328 index[index_ptr] = ftello(debug_fp);
324 329
325 // we should now have a complete index 330 // we should now have a complete index
326 fseek(debug_fp, index_pos, SEEK_SET); 331 fseeko(debug_fp, index_pos, SEEK_SET);
327 pst_debug_fwrite(index, index_size, 1, debug_fp); 332 pst_debug_fwrite(index, index_size, 1, debug_fp);
328 fseek(debug_fp, 0, SEEK_END); 333 fseeko(debug_fp, 0, SEEK_END);
329 item_ptr = item_head = item_tail = NULL; 334 item_ptr = item_head = item_tail = NULL;
330 free(index); 335 free(index);
331 if (buf) free(buf); 336 if (buf) free(buf);
332 } 337 }
333 338
341 off_t index_pos, file_pos; 346 off_t index_pos, file_pos;
342 char zero='\0'; 347 char zero='\0';
343 unsigned int end; 348 unsigned int end;
344 if (!debug_fp) return; // no file 349 if (!debug_fp) return; // no file
345 index[0] = 1; //only one item in this index 350 index[0] = 1; //only one item in this index
346 index_pos = ftell(debug_fp); 351 index_pos = ftello(debug_fp);
347 pst_debug_fwrite(index, index_size, 1, debug_fp); 352 pst_debug_fwrite(index, index_size, 1, debug_fp);
348 353
349 index[1] = ftell(debug_fp); 354 index[1] = ftello(debug_fp);
350 355
351 if (size > USHRT_MAX) { // bigger than can be stored in a short 356 if (size > USHRT_MAX) { // bigger than can be stored in a short
352 rec_type = 'L'; 357 rec_type = 'L';
353 pst_debug_fwrite(&rec_type, 1, sizeof(char), debug_fp); 358 pst_debug_fwrite(&rec_type, 1, sizeof(char), debug_fp);
354 lfile_rec.type = item->type; 359 lfile_rec.type = item->type;
365 mfile_rec.funcname = 0; 370 mfile_rec.funcname = 0;
366 mfile_rec.filename = strlen(item->function)+1; 371 mfile_rec.filename = strlen(item->function)+1;
367 mfile_rec.text = mfile_rec.filename+strlen(item->file)+1; 372 mfile_rec.text = mfile_rec.filename+strlen(item->file)+1;
368 pst_debug_fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp); 373 pst_debug_fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp);
369 } 374 }
370 file_pos = ftell(debug_fp); 375 file_pos = ftello(debug_fp);
371 pst_debug_fwrite(item->function, strlen(item->function)+1, 1, debug_fp); 376 pst_debug_fwrite(item->function, strlen(item->function)+1, 1, debug_fp);
372 pst_debug_fwrite(item->file, strlen(item->file)+1, 1, debug_fp); 377 pst_debug_fwrite(item->file, strlen(item->file)+1, 1, debug_fp);
373 vfprintf(debug_fp, fmt, *ap); 378 vfprintf(debug_fp, fmt, *ap);
374 pst_debug_fwrite(&zero, 1, 1, debug_fp); 379 pst_debug_fwrite(&zero, 1, 1, debug_fp);
375 380
376 end = ftell(debug_fp)-file_pos; 381 end = (unsigned int) (ftello(debug_fp) - file_pos);
377 382
378 index[2] = ftell(debug_fp); 383 index[2] = ftello(debug_fp);
379 fseek(debug_fp, index_pos, SEEK_SET); 384 fseeko(debug_fp, index_pos, SEEK_SET);
380 pst_debug_fwrite(index, index_size, 1, debug_fp); 385 pst_debug_fwrite(index, index_size, 1, debug_fp);
381 if (size > USHRT_MAX) { 386 if (size > USHRT_MAX) {
382 pst_debug_fwrite(&rec_type, 1, sizeof(char), debug_fp); 387 pst_debug_fwrite(&rec_type, 1, sizeof(char), debug_fp);
383 lfile_rec.end = end; 388 lfile_rec.end = end;
384 pst_debug_fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); 389 pst_debug_fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp);
385 } else { 390 } else {
386 pst_debug_fwrite(&rec_type, 1, sizeof(char), debug_fp); 391 pst_debug_fwrite(&rec_type, 1, sizeof(char), debug_fp);
387 mfile_rec.end = end; 392 mfile_rec.end = end;
388 pst_debug_fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp); 393 pst_debug_fwrite(&mfile_rec, sizeof(mfile_rec), 1, debug_fp);
389 } 394 }
390 fseek(debug_fp, 0, SEEK_END); 395 fseeko(debug_fp, 0, SEEK_END);
391 } 396 }
392 397
393 398
394 void pst_debug_write_hex(struct pst_debug_item *item, char *buf, size_t size, int col) { 399 void pst_debug_write_hex(struct pst_debug_item *item, char *buf, size_t size, int col) {
395 struct pst_debug_file_rec_l lfile_rec; 400 struct pst_debug_file_rec_l lfile_rec;
399 char zero='\0'; 404 char zero='\0';
400 if (!debug_fp) return; // no file 405 if (!debug_fp) return; // no file
401 index[0] = 1; // only one item in this index run 406 index[0] = 1; // only one item in this index run
402 index[1] = 0; // valgrind, avoid writing uninitialized data 407 index[1] = 0; // valgrind, avoid writing uninitialized data
403 index[2] = 0; // "" 408 index[2] = 0; // ""
404 index_pos = ftell(debug_fp); 409 index_pos = ftello(debug_fp);
405 pst_debug_fwrite(index, index_size, 1, debug_fp); 410 pst_debug_fwrite(index, index_size, 1, debug_fp);
406 index[1] = ftell(debug_fp); 411 index[1] = ftello(debug_fp);
407 412
408 // always use the long 413 // always use the long
409 rec_type = 'L'; 414 rec_type = 'L';
410 pst_debug_fwrite(&rec_type, 1, sizeof(char), debug_fp); 415 pst_debug_fwrite(&rec_type, 1, sizeof(char), debug_fp);
411 lfile_rec.funcname = 0; 416 lfile_rec.funcname = 0;
414 lfile_rec.end = 0; // valgrind, avoid writing uninitialized data 419 lfile_rec.end = 0; // valgrind, avoid writing uninitialized data
415 lfile_rec.line = item->line; 420 lfile_rec.line = item->line;
416 lfile_rec.type = item->type; 421 lfile_rec.type = item->type;
417 pst_debug_fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); 422 pst_debug_fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp);
418 423
419 file_pos = ftell(debug_fp); 424 file_pos = ftello(debug_fp);
420 pst_debug_fwrite(item->function, strlen(item->function)+1, 1, debug_fp); 425 pst_debug_fwrite(item->function, strlen(item->function)+1, 1, debug_fp);
421 pst_debug_fwrite(item->file, strlen(item->file)+1, 1, debug_fp); 426 pst_debug_fwrite(item->file, strlen(item->file)+1, 1, debug_fp);
422 427
423 pst_debug_hexdumper(debug_fp, buf, size, col, 0); 428 pst_debug_hexdumper(debug_fp, buf, size, col, 0);
424 pst_debug_fwrite(&zero, 1, 1, debug_fp); 429 pst_debug_fwrite(&zero, 1, 1, debug_fp);
425 lfile_rec.end = ftell(debug_fp) - file_pos; 430 lfile_rec.end = ftello(debug_fp) - file_pos;
426 431
427 index[2] = ftell(debug_fp); 432 index[2] = ftello(debug_fp);
428 fseek(debug_fp, index_pos, SEEK_SET); 433 fseeko(debug_fp, index_pos, SEEK_SET);
429 pst_debug_fwrite(index, index_size, 1, debug_fp); 434 pst_debug_fwrite(index, index_size, 1, debug_fp);
430 pst_debug_fwrite(&rec_type, 1, sizeof(char), debug_fp); 435 pst_debug_fwrite(&rec_type, 1, sizeof(char), debug_fp);
431 pst_debug_fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp); 436 pst_debug_fwrite(&lfile_rec, sizeof(lfile_rec), 1, debug_fp);
432 fseek(debug_fp, 0, SEEK_END); 437 fseeko(debug_fp, 0, SEEK_END);
433 } 438 }
434 439
435 440
436 void *xmalloc(size_t size) { 441 void *xmalloc(size_t size) {
437 void *mem = malloc(size); 442 void *mem = malloc(size);