Messages in this thread | | | From | Darryl Miles <> | Subject | Re: why doesn't the following cause a coredump in Linux? | Date | Sun, 6 Jul 1997 12:57:11 +0100 |
| |
In article <Pine.LNX.3.96.970705221241.9422A-100000@bibendum.3Sheep.COM> you wrote: : The following program will not cause a coredump even though it looks like : I am assigning a value to a illegal memory reference. Why is this?
First of all your questions would be better aired on the newsgroup comp.os.linux.development.apps maybe even comp.unix.programmer. The linux-kernel list is for kernel specific discussion.
Variable 'a' comes out of dynamic storage from malloc (and friends). The memory malloc uses is allocated by the kernel to the application at 4Kb granuality (under i386). This generally forms a contigious area of virtual address space, all of which is legally addressable for read and write by the application.
If 'a' = (double **)0x800010
: a[0][0]=255;
is
*((double *)0x800010) = 255;
: a[0][5]=256;
is
*((double *)(0x800010 + (5 * sizeof(double)))) = 255;
or
*((double *)0x800038) = 255;
When you called calloc() it probably asked the kernel for another 4Kb page (because you've never called calloc before in the application so it has until now, no memory to handout, not because all malloc requests use up a 4Kb page). It probably allocated 0x800000 to 0x801000 in the above fictional case. Which means the application can legally address any byte in this memory region.
So even though your memory reference is techinically out-of-bounds, it doesn't cause a crash because the memory writes it performs are not to illegal areas of memory.
You will probably find that if your application continuted to use malloc (and friends) it would crash further down the line when it tried allocating or freeing a block, or that a piece of your application data gets corrupted and if you're really lucky you hit an area of memory not yet allocated by malloc and also not part of mallocs internal memory management data structures, in which case you may never know about the bug.
: Am I : allocating more memory than I need in my dim2d or am I allocating it the : wrong way?
No, but the underlying malloc function is allocating a little bit more than it probably needs to, but this really makes no difference in this general programming error, since if your application ran a bit doing more mallocs (like programs do) then executed this code you'd still be writing over bits of memory which it's shouldn't be.
: I am not sure why the main() references won't cause a core : dump, since it looks like I'm poking past the array's boundaries (at least : in the static case, one would think so).
Variable 'a2' this is automatic (not static) and storage is located on the stack. What you'll be doing here is probably overwriting part of the command line arguments or environment space. I think I am correct in saying that Linux puts the command line arguments and enviroment variables onto the stack before calling main with the count and pointers back to the stack space to give the application argc, argv[] and environ[].
In:
a2[0][5]=256
If it were any less than 5, you'd probably start overwriting the return address for main() (and cause a crash on the way out of main, usualy leaving 'gdb' with a 'bracktrace' of garbage). If it were a little less still you've be overwriting some registers saved to remember the amount of space used by automatic variables, this shows up as a similar result to overwriting the return address. If it were a little less again you'd overwrite the variable 'a' until finally you get to a2[0][0] and you'd be writing into variable 'a2'. Obviously 'a2' is 8 bytes long (on i386) the you may only find a2[0][1] = xxx or a2[0][2] = xxx, wipes some or all of the above out.
So the reason this doesn't crash is because you're again writing into memory which you're legally allowed to perform a write operation on.
If you were to walk the argv[] of environ[] tables and strings before and after access you'd probably find something got corrupted.
: -- : #include <stdio.h> : #include <stdlib.h>
: double **dim2d(int n, int m) /* n = # of rows, m = # of columns */ : { : int i; : double **narr; : narr=(double **)calloc(n, sizeof(double *)); : if (narr == NULL) return NULL; : for (i=0; i < n; i++) { : narr[i]=(double *)calloc(m, sizeof(double)); : if (narr[i] == NULL) return NULL; : } : return narr; : }
: main() : { : double **a=dim2d(1,1); : double a2[1][1]; : a[0][0]=255; : a[0][5]=256;
: a2[0][0]=255; : a2[0][5]=256; : }
-- Darryl Miles
| |