> Dennis: > > You shot yourself in the foot. I am not so sure.
There is a fault somewhere in Solaris 10 I think. I am guessing and am hunting for proof. I have a wee mystery as to why this works flawlessly on every linux I tried thus far as well as on Solaris 8 i386 and also on Solaris 10 when I compile as a 32-bit generic binary. Please see below because I am having a hard time finding the data. > int *comb; > ... > comb = ( int * ) calloc( (size_t) k, sizeof(int) ); > for ( i = 0; i < k; ++i) > *( comb + i * sizeof(int) ) = i; > > 'comb' is a pointer to an int. *nod* > As such, 'comb + n' is really '(caddr_t)comb + n * sizeof (int))' Really? Let's check that with dbx. I was thinking the same way as you and made the mistake of allocating too much memory in line 95. The calloc was at line 95 in main thus : comb = ( int * ) calloc( (size_t) k, sizeof(int) ); So I have k * sizeof(int) bytes of memory made available to me. Too much. There only needs to be ( k-1 ) slots of sizeof(int), not k. Thus, in fact try this yourself and show me the error please : $ mdigest -a sha1 combinations.c b5ca76095a364ab67bd86863b6f94e006909aae7 combinations.c $ c99 $CFLAGS -o combinations combinations.c $ dbx combinations Reading combinations Reading ld.so.1 Reading libc.so.1 (dbx) stop at 95 (2) stop at "combinations.c":95 (dbx) run 30 22 > /dev/null Running: combinations 30 22 > /dev/null (process id 3507) stopped in main at line 95 in file "combinations.c" 95 comb = ( int * ) calloc( (size_t) k, sizeof(int) ); (dbx) print comb dbx: warning: cannot recreate macro information for combinations.c -- unrecognized compiler : /opt/solarisstudio12.3/prod/bin/c99 comb = (nil) (dbx) step Reading libc_psr.so.1 stopped in main at line 97 in file "combinations.c" 97 for ( i = 0; i < k; ++i) (dbx) print comb comb = 0x100101500 So comb points to memory at 0x100101500h and I expect k * sizeof(int) more bytes. (dbx) print *comb *comb = 0 (dbx) print sizeof(int) sizeof(int ) = 4 (dbx) print k k = 22 (dbx) print ( comb + 22 * 4 ) comb+22*4 = 0x100101660 That address looks correct to me. (dbx) print *( comb + 22 * 4 ) *(comb+22*4) = 0 We see calloc did its job of providing zeroed out memory up to there no problem. (dbx) stop at 101 (3) stop at "combinations.c":101 (dbx) cont stopped in main at line 101 in file "combinations.c" 101 printc( comb, k ); (dbx) print *( comb + 22 * 4 ) *(comb+22*4) = 0 like I said above .. too much memory. I never touched addr (comb + k * sizeof(int) ). (dbx) print *( comb + 21 * 4 ) *(comb+21*4) = 21 looks perfect to me, furthermore : (dbx) print *( comb + 21 * 4 ) *(comb+21*4) = 21 (dbx) print *( comb + 16 * 4 ) *(comb+16*4) = 16 (dbx) print *( comb + 8 * 4 ) *(comb+8*4) = 8 (dbx) print *( comb + 4 * 4 ) *(comb+4*4) = 4 (dbx) print *( comb + 2 * 4 ) *(comb+2*4) = 2 (dbx) print *( comb + 1 * 4 ) *(comb+1*4) = 1 (dbx) print *( comb ) *comb = 0 (dbx) cont signal SEGV (no mapping at the fault address) in _malloc_unlocked at 0xffffffff7ef63624 0xffffffff7ef63624: _malloc_unlocked+0x023c: ldx [%g5 + 16], %o1 Current function is printc 28 printf("{ "); (dbx) regs current frame: [6] g0-g1 0x0000000000000000 0x0000000600003f70 g2-g3 0x0000000000000000 0x0000000000000000 g4-g5 0x0000000600003f70 0x00000007001054d0 g6-g7 0x0000000000000000 0xffffffff7f100200 o0-o1 0x0000000100000fe8 0x0000000000000000 o2-o3 0x0000000000000000 0xffffffff7f1496dc o4-o5 0xffffffff7f13e000 0x0000000000000002 o6-o7 0xffffffff7fffec61 0x0000000100000b0c l0-l1 0x0000000100000fe8 0x0000000000000000 l2-l3 0x0000000000000000 0x0000000000000000 l4-l5 0x0000000000000000 0x0000000000000000 l6-l7 0x0000000000000000 0x00000001001010a8 i0-i1 0x0000000100101500 0x0000000000000016 i2-i3 0x0000000000000000 0xfffffffffffffff8 i4-i5 0x0000000000000000 0x0000000100101558 i6-i7 0xffffffff7fffed31 0x0000000100000f28 y 0x0000000000000000 ccr 0x0000000000000099 pc 0x0000000100000b0c:printc+0x2c call printf [PLT] ! 0x1001011e0 npc 0xffffffff7ef63628:_malloc_unlocked+0x240 and %o1, -3, %o0 (dbx) (dbx) quit $ Same code runs fine on Linux compiled with GCC 4.7.2. Same code runs fine on Solaris 8. Really .. I don't see where I end up looking at *(comb + some_offset) outside of the allocated area. Just for giggles here is the same situation on a Solaris 8 i386 boxen : titan-i386-SunOS5.8 $ dbx combinations Reading combinations Reading ld.so.1 Reading libc.so.1 Reading libdl.so.1 (dbx) stop at 95 (2) stop at "combinations.c":95 (dbx) run 30 22 > /dev/null Running: combinations 30 22 > /dev/null (process id 805) stopped in main at line 95 in file "combinations.c" 95 comb = ( int * ) calloc( (size_t) k, sizeof(int) ); (dbx) print comb comb = 0x8047a4c (dbx) step stopped in main at line 97 in file "combinations.c" 97 for ( i = 0; i < k; ++i) (dbx) print comb comb = 0x8060e18 (dbx) print *comb *comb = 0 (dbx) print sizeof(int) sizeof(int ) = 4 (dbx) print k k = 22 (dbx) print ( comb + 22 * 4 ) comb+22*4 = 0x8060f78 (dbx) print *( comb + 22 * 4 ) *(comb+22*4) = 1376259 (dbx) stop at 101 (3) stop at "combinations.c":101 (dbx) cont stopped in main at line 101 in file "combinations.c" 101 printc( comb, k ); (dbx) print *( comb + 22 * 4 ) *(comb+22*4) = 1376259 (dbx) print *( comb + 21 * 4 ) *(comb+21*4) = 21 (dbx) print *( comb + 16 * 4 ) *(comb+16*4) = 16 (dbx) print *( comb + 8 * 4 ) *(comb+8*4) = 8 (dbx) print *( comb + 4 * 4 ) *(comb+4*4) = 4 (dbx) print *( comb + 2 * 4 ) *(comb+2*4) = 2 (dbx) print *( comb + 1 * 4 ) *(comb+1*4) = 1 (dbx) print *( comb ) *comb = 0 (dbx) cont execution completed, exit code is 0 (dbx) quit titan-i386-SunOS5.8 $ No core dump. No problems. Let's go back to the T5240 and try a somewhat different compiler flag set to create a 32-bit binary : t5240 $ uname -a SunOS node002 5.10 Generic_147440-23 sun4v sparc SUNW,T5240 t5240 $ c99 -Xc -g -errfmt=error -erroff=%none -errwarn=%all -xstrconst -xildoff -m32 -xmemalign=8s -xnolibmil -xcode=pic32 -xregs=no%appl -xlibmieee -mc -xs -ftrap=%none -Qy -xbuiltin=%none -xunroll=1 -xtarget=generic \ > -D_TS_ERRNO -D_POSIX_PTHREAD_SEMANTICS -D_LARGEFILE64_SOURCE -o > combinations_32 combinations.c t5240 $ file combinations_32 combinations_32: ELF 32-bit MSB executable SPARC32PLUS Version 1, V8+ Required, dynamically linked, not stripped t5240 $ t5240 $ dbx combinations_32 Reading combinations_32 Reading ld.so.1 Reading libc.so.1 (dbx) stop at 95 (2) stop at "combinations.c":95 (dbx) run 30 22 > /dev/null Running: combinations_32 30 22 > /dev/null (process id 3806) stopped in main at line 95 in file "combinations.c" 95 comb = ( int * ) calloc( (size_t) k, sizeof(int) ); (dbx) print comb dbx: warning: cannot recreate macro information for combinations.c -- unrecognized compiler : /opt/solarisstudio12.3/prod/bin/c99 comb = (nil) (dbx) step Reading libc_psr.so.1 stopped in main at line 97 in file "combinations.c" 97 for ( i = 0; i < k; ++i) (dbx) print comb comb = 0x21050 (dbx) print *comb *comb = 0 (dbx) print sizeof(int) sizeof(int ) = 4 (dbx) print k k = 22 (dbx) print ( comb + 22 * 4 ) comb+22*4 = 0x211b0 (dbx) print ( comb + 21 * 4 ) comb+21*4 = 0x211a0 (dbx) stop at 101 (3) stop at "combinations.c":101 (dbx) cont stopped in main at line 101 in file "combinations.c" 101 printc( comb, k ); (dbx) print *( comb + 21 * 4 ) *(comb+21*4) = 21 (dbx) print *( comb + 16 * 4 ) *(comb+16*4) = 16 (dbx) print *( comb + 8 * 4 ) *(comb+8*4) = 8 (dbx) print *( comb + 1 * 4 ) *(comb+1*4) = 1 (dbx) print *( comb ) *comb = 0 (dbx) cont execution completed, exit code is 0 (dbx) quit t5240 $ Again, no core dump, no problems. On the T5240 .. watch this : t5240 $ ./combinations_32 30 22 > /dev/null t5240 $ No problem. t5240 $ ./combinations_32 30 22 > /tmp/big_case_C22of30.dat So there is a problem ... but not in pointers. At least, I don't see consistent behavior between Solaris 10, Solaris 8, RHEL and also inconsistent behavior between a 64-bit binary and a 32-bit binary. > causing heap corruption, which leads to the core dump. > > The line should read: > *( comb + i ) = i; Well this was a post to a website that seems "educational" or at least an on going discussion about the topic. I thought that using the syntax *(comb + offset ) was more clear than comb[j]. > You were just lucky that it worked at all > with the first set of parameters. The problem is .. it works everywhere on Linux. On Red Hat Enterprise Linux. On Debian linux also. Only on Solaris 10 with the exact same parameters does it segfault. On Solaris 8 i386 this thing runs. That was what really bothered me. I hacked this up on a RHEL workstation first and then took it over to Solaris 10 on a T5240 where it ran just fine about twenty times .. until I hit this case. Anyways, there is something odd going on here between Solaris 10, Solaris 8 and RHEL. Dennis _______________________________________________ opensolaris-code mailing list opensolaris-code@opensolaris.org http://mail.opensolaris.org/mailman/listinfo/opensolaris-code