> 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
[email protected]
http://mail.opensolaris.org/mailman/listinfo/opensolaris-code