SXSAW%ALASKA.BITNET@wiscvm.wisc.EDU (05/12/87)
For those people using malloc to do the incredible indirection.... First off - you don't need a dissassembler to look at the MACRO code that C produces. When you invoke the C compiler, simply do a $ CC/LIST/MACHINE src-file The C compiler will then create a src-file.LIS which has the machine code interspersed with the source code (VERY HANDY) - see HELP CC for more information (this of course assumes you are using DEC's C). Second - don't use MALLOC, malloc is a) not ast re-entrent, and b) probably incorrectly coded - I say probably since I have been unable to get CSC to confirm a few tidbits of info for me. The C manual states that the allocation/deallocation routines will keep the last FREE'd block for possible re-use in a subsequent MALLOC - This works great as long as the routines DON'T decide to break up the block of memory - which they will happily do, i.e. If the chunk requested is smaller than what is saved, it breaks off only the chunk requested - keeping the leftovers for subsequent calls to MALLOC - the fun starts when they call LIB$FREE_VM to release these "chunks". The RTL manual states in BIG BOLD LETTERS that "Thou shalt not LIB$FREE_VM partial blocks which were allocated via LIB$GET_VM". Maybe the C developers know something about GET_VM and FREE_VM that we don't?? Note that I AM NOT saying that this is in fact the problem - just that it may be a POTENTIAL problem. Re AST re-entrency - Since the alloc/dealloc routines save the size and address of FREE'd blocks across calls - to manipulate later, and since the code can be interrupted during this manipulation via an AST routine which calls MALLOC - well....... It only takes about 10 lines of code to create a test case for this that WILL FAIL sometimes - and sometimes not, depends on the timing. (with this type of coding going on in the CRTL I begin to wonder about other routines) I have generally found that with VMS4.x and the additional features added to LIB$GET_VM, etc. (i.e. the memory ZONE concepts) - that the best way to go is use the RTL procedures. naturally you code will be less portable, but.... Just a side note - I would be really surprised if the compiler is incorrectly handling the indirection. Indirection is easy for a compiler to do on a VAX and also easy for the programmer to "mess up" - all it takes is one "bad" link. Something you might try (common debugging technique) is to reduce the code to its bare essentials, that is just the code necessary to do the MALLOC's and build your links - easy to test.
levy@ttrdc.UUCP (Daniel R. Levy) (05/13/87)
In article <7331@brl-adm.ARPA>, SXSAW%ALASKA.BITNET@wiscvm.wisc.EDU writes: < Re AST re-entrency - Since the alloc/dealloc routines save the size and < address of FREE'd blocks across calls - to manipulate later, and since the < code can be interrupted during this manipulation via an AST routine which < calls MALLOC - well....... It only takes about 10 lines of code to create < a test case for this that WILL FAIL sometimes - and sometimes not, depends < on the timing. (with this type of coding going on in the CRTL I begin to < wonder about other routines) I have generally found that with VMS4.x and < the additional features added to LIB$GET_VM, etc. (i.e. the memory ZONE < concepts) - that the best way to go is use the RTL procedures. naturally < you code will be less portable, but.... It is not a good idea to use malloc() re-entrantly in an interrupt service routine even on a UNIX system. The code below illustrates the problem on a System V release 2 3B20 (will core dump with a memory fault) when run and given rapidly repeated keyboard interrupts, unless PROTECT_MALLOC is #define'd. This ought to work just fine on VMS, too. -------- #include <signal.h> main() { int astrtn(); int i; char *malloc(); char *c; void exit(); (void) signal(SIGINT,astrtn); for (;;) { #ifdef PROTECT_MALLOC (void) signal(SIGINT,SIG_IGN); #endif if (!(c=malloc((unsigned)100))) { (void) write(1,"malloc() failure\n",(unsigned)17); exit(1); } #ifdef PROTECT_MALLOC (void) signal(SIGINT,astrtn); #endif for (i=0; i<100; i++) *c++ = 'y'; } } astrtn() { char *d; char *malloc(); void exit(); int i; (void) signal(SIGINT,SIG_IGN); (void) write(1,"INTERRUPT\n",(unsigned)10); if (!(d=malloc((unsigned)100))) { (void) write(1,"astrtn malloc failure\n",(unsigned)22); exit(2); } for (i=0; i<100; i++) *d++ = 'x'; (void) signal(SIGINT,astrtn); return 0; } -------- -- |------------dan levy------------| Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa, | an engihacker @ | vax135}!ttrdc!ttrda!levy | at&t computer systems division | Disclaimer: try datclaimer. |--------skokie, illinois--------|