00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #ifndef lint
00054 static const char RCSmalloc[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/libbu/malloc.c,v 14.26 2006/08/31 23:16:38 lbutler Exp $ (ARL)";
00055 #endif
00056
00057 #include "common.h"
00058
00059 #include <stdlib.h>
00060 #include <stdio.h>
00061 #ifdef HAVE_STRING_H
00062 # include <string.h>
00063 #else
00064 # include <strings.h>
00065 #endif
00066 #ifdef HAVE_UNISTD_H
00067 # include <unistd.h>
00068 #endif
00069
00070 #include "machine.h"
00071 #include "bu.h"
00072
00073
00074 int bu_debug = 0;
00075
00076
00077
00078
00079
00080
00081 typedef enum {
00082 MALLOC,
00083 CALLOC
00084 } alloc_t;
00085
00086
00087
00088 long bu_n_malloc = 0;
00089 long bu_n_free = 0;
00090 long bu_n_realloc = 0;
00091
00092 #define MDB_MAGIC 0x12348969
00093 struct memdebug {
00094 long magic;
00095 genptr_t mdb_addr;
00096 const char *mdb_str;
00097 int mdb_len;
00098 };
00099 static struct memdebug *bu_memdebug = (struct memdebug *)NULL;
00100 static struct memdebug *bu_memdebug_lowat = (struct memdebug *)NULL;
00101 static size_t bu_memdebug_len = 0;
00102 #define MEMDEBUG_NULL ((struct memdebug *)0)
00103
00104 struct memqdebug {
00105 struct bu_list q;
00106 struct memdebug m;
00107 };
00108
00109 static struct bu_list *bu_memq = BU_LIST_NULL;
00110 static struct bu_list bu_memqhd;
00111 #define MEMQDEBUG_NULL ((struct memqdebug *)0)
00112
00113 const char bu_strdup_message[] = "bu_strdup string";
00114 extern const char bu_vls_message[];
00115
00116
00117 #ifdef _WIN32
00118 char *sbrk(i)
00119 {
00120 return( (char *)0 );
00121 }
00122 #endif
00123
00124
00125
00126
00127
00128
00129
00130 HIDDEN void
00131 bu_memdebug_add(char *ptr, unsigned int cnt, const char *str)
00132 {
00133 register struct memdebug *mp;
00134 top:
00135 bu_semaphore_acquire( BU_SEM_SYSCALL );
00136 if( bu_memdebug ) {
00137 mp = &bu_memdebug[bu_memdebug_len-1];
00138 if( bu_memdebug_lowat > bu_memdebug &&
00139 bu_memdebug_lowat < mp ) {
00140 mp = bu_memdebug_lowat;
00141 } else {
00142 bu_memdebug_lowat = mp;
00143 }
00144 again:
00145 for( ; mp >= bu_memdebug; mp-- ) {
00146
00147 if( mp->mdb_len > 0 ) continue;
00148 mp->magic = MDB_MAGIC;
00149 mp->mdb_addr = ptr;
00150 mp->mdb_len = cnt;
00151 mp->mdb_str = str;
00152 bu_memdebug_lowat = mp-1;
00153 bu_semaphore_release( BU_SEM_SYSCALL );
00154 return;
00155 }
00156
00157 mp = &bu_memdebug[bu_memdebug_len-1];
00158 if( bu_memdebug_lowat != mp ) {
00159 bu_memdebug_lowat = mp;
00160 goto again;
00161 }
00162 }
00163
00164
00165 if( bu_memdebug_len <= 0 ) {
00166 bu_memdebug_len = 5120-2;
00167 bu_memdebug = (struct memdebug *)calloc(
00168 bu_memdebug_len, sizeof(struct memdebug) );
00169 if( bu_memdebug == (struct memdebug *)0 )
00170 bu_bomb("bu_memdebug_add() malloc failure\n");
00171 } else {
00172 size_t old_len = bu_memdebug_len;
00173 bu_memdebug_len *= 16;
00174 bu_memdebug = (struct memdebug *)realloc(
00175 (char *)bu_memdebug,
00176 sizeof(struct memdebug) * bu_memdebug_len );
00177 if( bu_memdebug == (struct memdebug *)0 )
00178 bu_bomb("bu_memdebug_add() malloc failure\n");
00179 bzero( (char *)&bu_memdebug[old_len],
00180 (bu_memdebug_len-old_len) * sizeof(struct memdebug) );
00181 }
00182 bu_semaphore_release( BU_SEM_SYSCALL );
00183
00184 goto top;
00185 }
00186
00187
00188
00189
00190
00191
00192 HIDDEN struct memdebug *
00193 bu_memdebug_check(register char *ptr, const char *str)
00194 {
00195 register struct memdebug *mp = &bu_memdebug[bu_memdebug_len-1];
00196 register long *ip;
00197
00198 if( bu_memdebug == (struct memdebug *)0 ) {
00199 bu_semaphore_acquire(BU_SEM_SYSCALL);
00200 fprintf(stderr,"bu_memdebug_check(x%lx, %s) no memdebug table yet\n",
00201 (long)ptr, str);
00202 bu_semaphore_release(BU_SEM_SYSCALL);
00203 return MEMDEBUG_NULL;
00204 }
00205 for( ; mp >= bu_memdebug; mp-- ) {
00206 if( !mp->magic ) continue;
00207 if( mp->magic != MDB_MAGIC ) bu_bomb("bu_memdebug_check() malloc tracing table corrupted!\n");
00208 if( mp->mdb_len <= 0 ) continue;
00209 if( mp->mdb_addr != ptr ) continue;
00210 ip = (long *)(ptr+mp->mdb_len-sizeof(long));
00211 if( *ip != MDB_MAGIC ) {
00212 bu_semaphore_acquire(BU_SEM_SYSCALL);
00213 fprintf(stderr,"ERROR bu_memdebug_check(x%lx, %s) %s, barrier word corrupted!\nbarrier at x%lx was=x%lx s/b=x%x, len=%d\n",
00214 (long)ptr, str, mp->mdb_str,
00215 (long)ip, *ip, MDB_MAGIC, mp->mdb_len);
00216 bu_semaphore_release(BU_SEM_SYSCALL);
00217 bu_bomb("bu_memdebug_check() memory corruption\n");
00218 }
00219 return(mp);
00220 }
00221 return MEMDEBUG_NULL;
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 static genptr_t
00239 bu_alloc(alloc_t type, unsigned int cnt, unsigned int sz, const char *str)
00240 {
00241 register genptr_t ptr;
00242 register unsigned long int size = cnt * sz;
00243
00244 if( size == 0 ) {
00245 fprintf(stderr,"ERROR: bu_alloc size=0 (cnt=%d, sz=%d) %s\n", cnt, sz, str );
00246 bu_bomb("ERROR: bu_malloc(0)\n");
00247 }
00248
00249 if( size < sizeof( int ) ) {
00250 size = sizeof( int );
00251 }
00252
00253 if( bu_debug&BU_DEBUG_MEM_CHECK ) {
00254
00255 size = (size+2*sizeof(long)-1)&(~(sizeof(long)-1));
00256 } else if (bu_debug&BU_DEBUG_MEM_QCHECK ) {
00257 size = (size+2*sizeof(struct memqdebug)-1)
00258 &(~(sizeof(struct memqdebug)-1));
00259 }
00260
00261 #if defined(MALLOC_NOT_MP_SAFE)
00262 bu_semaphore_acquire( BU_SEM_SYSCALL );
00263 #endif
00264
00265 switch (type) {
00266 case MALLOC:
00267 ptr = malloc(size);
00268 break;
00269 case CALLOC:
00270 #if defined(HAVE_CALLOC)
00271
00272
00273
00274 if( bu_debug&(BU_DEBUG_MEM_CHECK|BU_DEBUG_MEM_QCHECK) ) {
00275 ptr = malloc(size);
00276 bzero(ptr, size);
00277 } else {
00278 ptr = calloc(cnt, sz);
00279 }
00280 #else
00281 ptr = malloc(size);
00282 bzero(ptr, size);
00283 #endif
00284 break;
00285 default:
00286 bu_bomb("ERROR: bu_alloc with unknown type\n");
00287 }
00288
00289 if( ptr==(char *)0 || bu_debug&BU_DEBUG_MEM_LOG ) {
00290 fprintf(stderr, "%8lx malloc%7ld %s\n", (long)ptr, size, str);
00291 }
00292 #if defined(MALLOC_NOT_MP_SAFE)
00293 bu_semaphore_release( BU_SEM_SYSCALL );
00294 #endif
00295
00296 if( ptr==(char *)0 ) {
00297 fprintf(stderr,"bu_malloc: Insufficient memory available, sbrk(0)=x%lx\n", (long)sbrk(0));
00298 bu_bomb("bu_malloc: malloc failure");
00299 }
00300 if( bu_debug&BU_DEBUG_MEM_CHECK ) {
00301 bu_memdebug_add( ptr, size, str );
00302
00303
00304
00305
00306 *((long *)(((char *)ptr)+size-sizeof(long))) = MDB_MAGIC;
00307 } else if (bu_debug&BU_DEBUG_MEM_QCHECK ) {
00308 struct memqdebug *mp = (struct memqdebug *)ptr;
00309 ptr = (genptr_t)(((struct memqdebug *)ptr)+1);
00310 mp->m.magic = MDB_MAGIC;
00311 mp->m.mdb_addr = ptr;
00312 mp->m.mdb_len = size;
00313 mp->m.mdb_str = str;
00314 bu_semaphore_acquire(BU_SEM_SYSCALL);
00315 if (bu_memq == BU_LIST_NULL) {
00316 bu_memq = &bu_memqhd;
00317 BU_LIST_INIT(bu_memq);
00318 }
00319 BU_LIST_APPEND(bu_memq,&(mp->q));
00320 BU_LIST_MAGIC_SET(&(mp->q),MDB_MAGIC);
00321 bu_semaphore_release(BU_SEM_SYSCALL);
00322 }
00323 bu_n_malloc++;
00324 return(ptr);
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334 genptr_t
00335 bu_malloc(unsigned int size, const char *str)
00336 {
00337 return bu_alloc(MALLOC, 1, size, str);
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 genptr_t
00349 bu_calloc(unsigned int nelem, unsigned int elsize, const char *str)
00350 {
00351 return bu_alloc(CALLOC, nelem, elsize, str);
00352 }
00353
00354
00355
00356
00357
00358 void
00359 bu_free(genptr_t ptr, const char *str)
00360 {
00361 if(bu_debug&BU_DEBUG_MEM_LOG) {
00362 bu_semaphore_acquire(BU_SEM_SYSCALL);
00363 fprintf(stderr, "%8lx free %s\n", (long)ptr, str);
00364 bu_semaphore_release(BU_SEM_SYSCALL);
00365 }
00366 if(ptr == (char *)0 || ptr == (char *)(-1L) ) {
00367 fprintf(stderr,"%8lx free ERROR %s\n", (long)ptr, str);
00368 return;
00369 }
00370 if( bu_debug&BU_DEBUG_MEM_CHECK ) {
00371 struct memdebug *mp;
00372 if( (mp = bu_memdebug_check( ptr, str )) == MEMDEBUG_NULL ) {
00373 fprintf(stderr,"ERROR bu_free(x%lx, %s) pointer bad, or not allocated with bu_malloc! Ignored.\n", (long)ptr, str);
00374 } else {
00375 mp->mdb_len = 0;
00376 }
00377 } else if (bu_debug&BU_DEBUG_MEM_QCHECK ) {
00378 struct memqdebug *mp = ((struct memqdebug *)ptr)-1;
00379 if (BU_LIST_MAGIC_WRONG(&(mp->q),MDB_MAGIC)) {
00380 fprintf(stderr,"ERROR bu_free(x%lx, %s) pointer bad, or not allocated with bu_malloc! Ignored.\n", (long)ptr, str);
00381 } else {
00382 ptr = (genptr_t)mp;
00383 bu_semaphore_acquire(BU_SEM_SYSCALL);
00384 BU_LIST_DEQUEUE(&(mp->q));
00385 bu_semaphore_release(BU_SEM_SYSCALL);
00386 }
00387 }
00388
00389 #if defined(MALLOC_NOT_MP_SAFE)
00390 bu_semaphore_acquire(BU_SEM_SYSCALL);
00391 #endif
00392
00393 #ifndef _WIN32
00394 *((int *)ptr) = -1;
00395 #endif
00396 free(ptr);
00397 #if defined(MALLOC_NOT_MP_SAFE)
00398 bu_semaphore_release(BU_SEM_SYSCALL);
00399 #endif
00400 bu_n_free++;
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 genptr_t
00413 bu_realloc(register genptr_t ptr, unsigned int cnt, const char *str)
00414 {
00415 struct memdebug *mp=NULL;
00416 char *original_ptr;
00417
00418 if ( ! ptr ) {
00419
00420
00421
00422
00423 return bu_malloc(cnt, str);
00424 }
00425
00426 if( bu_debug&BU_DEBUG_MEM_CHECK ) {
00427 if( ptr && (mp = bu_memdebug_check( ptr, str )) == MEMDEBUG_NULL ) {
00428 fprintf(stderr,"%8lx realloc%6d %s ** barrier check failure\n",
00429 (long)ptr, cnt, str );
00430 }
00431
00432 cnt = (cnt+2*sizeof(long)-1)&(~(sizeof(long)-1));
00433 } else if ( bu_debug&BU_DEBUG_MEM_QCHECK ) {
00434 struct memqdebug *mp = ((struct memqdebug *)ptr)-1;
00435
00436 cnt = (cnt + 2*sizeof(struct memqdebug) - 1)
00437 &(~(sizeof(struct memqdebug)-1));
00438
00439 if (BU_LIST_MAGIC_WRONG(&(mp->q),MDB_MAGIC)) {
00440 fprintf(stderr,"ERROR bu_realloc(x%lx, %s) pointer bad, "
00441 "or not allocated with bu_malloc! Ignored.\n",
00442 (long)ptr, str);
00443
00444
00445
00446
00447
00448 return ptr;
00449 }
00450 ptr = (genptr_t)mp;
00451 BU_LIST_DEQUEUE(&(mp->q));
00452 }
00453
00454 original_ptr = ptr;
00455
00456 #if defined(MALLOC_NOT_MP_SAFE)
00457 bu_semaphore_acquire(BU_SEM_SYSCALL);
00458 #endif
00459 ptr = realloc(ptr,cnt);
00460 #if defined(MALLOC_NOT_MP_SAFE)
00461 bu_semaphore_release(BU_SEM_SYSCALL);
00462 #endif
00463
00464 if( ptr==(char *)0 || bu_debug&BU_DEBUG_MEM_LOG ) {
00465 bu_semaphore_acquire(BU_SEM_SYSCALL);
00466 if (ptr == original_ptr) {
00467 fprintf(stderr,"%8lx realloc%6d %s [grew in place]\n",
00468 (long)ptr, cnt, str );
00469 } else {
00470 fprintf(stderr,"%8lx realloc%6d %s [moved from %8lx]\n",
00471 (long)ptr, cnt, str, original_ptr);
00472 }
00473
00474 bu_semaphore_release(BU_SEM_SYSCALL);
00475 }
00476 if( ptr==(char *)0 && cnt > 0 ) {
00477 fprintf(stderr,"bu_realloc: Insufficient memory available, sbrk(0)=x%lx\n", (long)sbrk(0));
00478 bu_bomb("bu_realloc: malloc failure");
00479 }
00480 if( bu_debug&BU_DEBUG_MEM_CHECK && ptr ) {
00481
00482 bu_semaphore_acquire(BU_SEM_SYSCALL);
00483 mp->mdb_addr = ptr;
00484 mp->mdb_len = cnt;
00485
00486
00487
00488 *((long *)(((char *)ptr)+cnt-sizeof(long))) = MDB_MAGIC;
00489 bu_semaphore_release(BU_SEM_SYSCALL);
00490 } else if ( bu_debug&BU_DEBUG_MEM_QCHECK && ptr ) {
00491 struct memqdebug *mp;
00492 bu_semaphore_acquire(BU_SEM_SYSCALL);
00493 mp = (struct memqdebug *)ptr;
00494 ptr = (genptr_t)(((struct memqdebug *)ptr)+1);
00495 mp->m.magic = MDB_MAGIC;
00496 mp->m.mdb_addr = ptr;
00497 mp->m.mdb_len = cnt;
00498 mp->m.mdb_str = str;
00499 BU_ASSERT(bu_memq != BU_LIST_NULL);
00500 BU_LIST_APPEND(bu_memq,&(mp->q));
00501 BU_LIST_MAGIC_SET(&(mp->q),MDB_MAGIC);
00502 bu_semaphore_release(BU_SEM_SYSCALL);
00503 }
00504 bu_n_realloc++;
00505 return(ptr);
00506 }
00507
00508
00509
00510
00511
00512
00513
00514 void
00515 bu_prmem(const char *str)
00516 {
00517 register struct memdebug *mp;
00518 register struct memqdebug *mqp;
00519 register long *ip;
00520 register size_t count = 0;
00521
00522 fprintf(stderr,"\nbu_prmem(): dynamic memory use (%s)\n", str);
00523 if( (bu_debug&(BU_DEBUG_MEM_CHECK|BU_DEBUG_MEM_QCHECK)) == 0 ) {
00524 fprintf(stderr,"\tMemory debugging is now OFF\n");
00525 }
00526 #if 0
00527 fprintf(stderr,"\t%ld slots in memdebug table (not # of allocs)\n Address Length Purpose\n",
00528 (long)bu_memdebug_len);
00529 #else
00530 fprintf(stderr," Address Length Purpose\n");
00531 #endif
00532 if( bu_memdebug_len > 0 ) {
00533 mp = &bu_memdebug[bu_memdebug_len-1];
00534 for( ; mp >= bu_memdebug; mp-- ) {
00535 if( !mp->magic ) continue;
00536 if( mp->magic != MDB_MAGIC ) bu_bomb("bu_memdebug_check() malloc tracing table corrupted!\n");
00537 if( mp->mdb_len <= 0 ) continue;
00538
00539 count++;
00540 ip = (long *)(((char *)mp->mdb_addr)+mp->mdb_len-sizeof(long));
00541 if( mp->mdb_str == bu_strdup_message ) {
00542 fprintf(stderr,"%8lx %6d bu_strdup: \"%s\"\n",
00543 (long)(mp->mdb_addr), mp->mdb_len,
00544 ((char *)mp->mdb_addr) );
00545 } else if( mp->mdb_str == bu_vls_message ) {
00546 fprintf(stderr,"%8lx %6d bu_vls: \"%s\"\n",
00547 (long)(mp->mdb_addr), mp->mdb_len,
00548 ((char *)mp->mdb_addr) );
00549 } else {
00550 fprintf(stderr,"%8lx %6d %s\n",
00551 (long)(mp->mdb_addr), mp->mdb_len,
00552 mp->mdb_str);
00553 }
00554 if( *ip != MDB_MAGIC ) {
00555 fprintf(stderr,"\tCorrupted end marker was=x%lx\ts/b=x%x\n",
00556 *ip, MDB_MAGIC);
00557 }
00558 }
00559 }
00560
00561
00562 if (bu_memq != BU_LIST_NULL) {
00563 fprintf(stderr,"memdebug queue\n Address Length Purpose\n");
00564 BU_LIST_EACH(bu_memq, mqp, struct memqdebug) {
00565 if (BU_LIST_MAGIC_WRONG(&(mqp->q),MDB_MAGIC)
00566 || BU_LIST_MAGIC_WRONG(&(mqp->m),MDB_MAGIC))
00567 bu_bomb("bu_prmem() malloc tracing queue corrupted!\n");
00568 if( mqp->m.mdb_str == bu_strdup_message ) {
00569 fprintf(stderr,"%8lx %6d bu_strdup: \"%s\"\n",
00570 (long)(mqp->m.mdb_addr), mqp->m.mdb_len,
00571 ((char *)mqp->m.mdb_addr) );
00572 } else if( mqp->m.mdb_str == bu_vls_message ) {
00573 fprintf(stderr,"%8lx %6d bu_vls: \"%s\"\n",
00574 (long)(mqp->m.mdb_addr), mqp->m.mdb_len,
00575 ((char *)mqp->m.mdb_addr) );
00576 } else {
00577 fprintf(stderr,"%8lx %6d %s\n",
00578 (long)(mqp->m.mdb_addr), mqp->m.mdb_len,
00579 mqp->m.mdb_str);
00580 }
00581 }
00582 }
00583
00584 fprintf(stderr, "%lu allocation entries\n", count);
00585
00586
00587 }
00588
00589
00590
00591
00592
00593
00594
00595 #if 0
00596 char *
00597 bu_strdup(register const char *cp)
00598 {
00599 return bu_strdupm(cp, bu_strdup_message);
00600 }
00601 #endif
00602 char *
00603 bu_strdupm(register const char *cp, const char *label)
00604 {
00605 register char *base;
00606 register size_t len;
00607
00608 len = strlen( cp )+2;
00609 base = bu_malloc( len, label);
00610
00611 if(bu_debug&BU_DEBUG_MEM_LOG) {
00612 bu_semaphore_acquire(BU_SEM_SYSCALL);
00613 fprintf(stderr, "%8lx strdup%7ld \"%s\"\n", (long)base, (long)len, cp );
00614 bu_semaphore_release(BU_SEM_SYSCALL);
00615 }
00616
00617 memcpy( base, cp, len );
00618 return(base);
00619 }
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640 char *
00641 bu_dirname(const char *cp)
00642 {
00643 char *ret;
00644 char *slash;
00645 int len;
00646
00647
00648 if( cp == NULL ) return bu_strdup(".");
00649 if( strcmp( cp, "/" ) == 0 )
00650 return bu_strdup("/");
00651 if( strcmp( cp, "." ) == 0 ||
00652 strcmp( cp, ".." ) == 0 ||
00653 strrchr(cp, '/') == NULL )
00654 return bu_strdup(".");
00655
00656
00657 ret = bu_strdup(cp);
00658
00659
00660 len = strlen(ret);
00661 if( ret[len-1] == '/' ) ret[len-1] = '\0';
00662
00663
00664 if( (slash = strrchr(ret, '/')) == NULL ) {
00665 bu_free( ret, "bu_dirname" );
00666 return bu_strdup(".");
00667 }
00668
00669
00670 if( slash == ret )
00671 ret[1] = '\0';
00672 else
00673 *slash = '\0';
00674
00675 return ret;
00676 }
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695 int
00696 bu_malloc_len_roundup(register int nbytes)
00697 {
00698 #if !defined(HAVE_CALTECH_MALLOC)
00699 return(nbytes);
00700 #else
00701 static int pagesz;
00702 register int n;
00703 register int amt;
00704
00705 if (pagesz == 0)
00706 pagesz = getpagesize();
00707
00708 #define OVERHEAD (4*sizeof(unsigned char) + \
00709 2*sizeof(unsigned short) + \
00710 sizeof(unsigned int) )
00711 n = pagesz - OVERHEAD;
00712 if (nbytes <= n)
00713 return(n);
00714 amt = pagesz;
00715
00716 while (nbytes > amt + n) {
00717 amt <<= 1;
00718 }
00719 return(amt-OVERHEAD-sizeof(int));
00720 #endif
00721 }
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 void
00736 bu_ck_malloc_ptr(genptr_t ptr, const char *str)
00737 {
00738 register struct memdebug *mp = &bu_memdebug[bu_memdebug_len-1];
00739 register long *ip;
00740
00741
00742 if (ptr == (char *)NULL) {
00743 fprintf(stderr,"bu_ck_malloc_ptr(x%lx, %s) null pointer\n\n", (long)ptr, str);
00744 bu_bomb("Goodbye");
00745 }
00746
00747 if (bu_debug&BU_DEBUG_MEM_CHECK) {
00748 if( bu_memdebug == (struct memdebug *)0 ) {
00749 fprintf(stderr,"bu_ck_malloc_ptr(x%lx, %s) no memdebug table yet\n",
00750 (long)ptr, str);
00751
00752 return;
00753 }
00754
00755 for( ; mp >= bu_memdebug; mp-- ) {
00756 if( !mp->magic ) continue;
00757 if( mp->magic != MDB_MAGIC ) bu_bomb("bu_ck_malloc_ptr() malloc tracing table corrupted!\n");
00758 if( mp->mdb_len <= 0 || mp->mdb_addr != ptr ) continue;
00759
00760
00761 ip = (long *)(((char *)ptr)+mp->mdb_len-sizeof(long));
00762 if( *ip != MDB_MAGIC ) {
00763 fprintf(stderr,"ERROR bu_ck_malloc_ptr(x%lx, %s) barrier word corrupted! was=x%lx s/b=x%x\n",
00764 (long)ptr, str, (long)*ip, MDB_MAGIC);
00765 bu_bomb("bu_ck_malloc_ptr\n");
00766 }
00767 return;
00768 }
00769 fprintf(stderr,"WARNING: bu_ck_malloc_ptr(x%lx, %s)\
00770 pointer not in table of allocated memory.\n", (long)ptr, str);
00771 } else if (bu_debug&BU_DEBUG_MEM_QCHECK) {
00772 struct memqdebug *mp = (struct memqdebug *)ptr;
00773 if (BU_LIST_MAGIC_WRONG(&(mp->q),MDB_MAGIC)
00774 || mp->m.magic != MDB_MAGIC) {
00775 fprintf(stderr,"WARNING: bu_ck_malloc_ptr(x%lx, %s)"
00776 " memory corrupted.\n", (long)ptr, str);
00777 }
00778 }
00779 }
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795 int
00796 bu_mem_barriercheck(void)
00797 {
00798 register struct memdebug *mp = &bu_memdebug[bu_memdebug_len-1];
00799 register long *ip;
00800
00801 if( bu_memdebug == (struct memdebug *)0 ) {
00802 fprintf(stderr,"bu_mem_barriercheck() no memdebug table yet\n");
00803 return 0;
00804 }
00805 bu_semaphore_acquire( BU_SEM_SYSCALL );
00806 for( ; mp >= bu_memdebug; mp-- ) {
00807 if( !mp->magic ) continue;
00808 if( mp->magic != MDB_MAGIC ) {
00809 bu_semaphore_release( BU_SEM_SYSCALL );
00810 fprintf(stderr," mp->magic = x%lx, s/b=x%x\n", (long)(mp->magic), MDB_MAGIC );
00811 bu_bomb("bu_mem_barriercheck() malloc tracing table corrupted!\n");
00812 }
00813 if( mp->mdb_len <= 0 ) continue;
00814 ip = (long *)(((char *)mp->mdb_addr)+mp->mdb_len-sizeof(long));
00815 if( *ip != MDB_MAGIC ) {
00816 bu_semaphore_release( BU_SEM_SYSCALL );
00817 fprintf(stderr,"ERROR bu_mem_barriercheck(x%lx, len=%d) barrier word corrupted!\n\tbarrier at x%lx was=x%lx s/b=x%x %s\n",
00818 (long)mp->mdb_addr, mp->mdb_len,
00819 (long)ip, *ip, MDB_MAGIC, mp->mdb_str);
00820 return -1;
00821 }
00822 }
00823 bu_semaphore_release( BU_SEM_SYSCALL );
00824 return 0;
00825 }
00826
00827
00828
00829
00830
00831
00832
00833 void bu_free_array(int argc, char *argv[], const char *str)
00834 {
00835 int count = 0;
00836
00837 if (!argv || argc <= 0) {
00838 return;
00839 }
00840
00841 while (count < argc) {
00842 if (argv[count]) {
00843 bu_free(argv[count], str);
00844 argv[count] = NULL;
00845 }
00846 count++;
00847 }
00848
00849 return;
00850 }
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862