zero sized heap memory in page aligned allocation` - c

I'm trying to study how Linux would behave if I were to allocate a 10 bytes of memory at every page boundary for a total of ten pages. Here is the program I could come up with:
1 #include <stdlib.h>$
2 #include <stdio.h>$
3 #include <time.h>$
4 #include <unistd.h>$
5 #include <string.h>$
6 $
7 #define PAGESIZE getpagesize()$
8 int main () {$
9 int *ArrP[10] = {NULL};$
10 int pgSz = PAGESIZE;$
11 int randnum;$
12 $
13
14 for (int i = 0; i < (sizeof(ArrP)/sizeof(int*)); i++) {$
15 if(posix_memalign((void **)&ArrP[i], pgSz, 10)) {$
16 perror("error getting page aligned mem: ");$
17 exit(1);$
18 }$
19 else$
20 printf("ArrP[%d] = %lu\n", i, ArrP[i]);$
21 }$
22 $
23 srand(time(0));$
24 while(1) {$
25 for (int i = 0; i <(sizeof(ArrP)/sizeof(int*)); i++) {$
26 randnum = rand();$
27 memcpy(ArrP[i], &randnum, sizeof(int));$
28 }$
29 }$
30 return 0;$
31 }$
However when I run it, the /proc/pid/maps file shows a heap size of 0.
here's the content of that file:
555555554000-555555555000 r--p 00000000 08:01 1966744 /home/AB1/ProgPractice/InternalFragmentation
555555555000-555555556000 r-xp 00001000 08:01 1966744 /home/AB1/ProgPractice/InternalFragmentation
555555556000-555555557000 r--p 00002000 08:01 1966744 /home/AB1/ProgPractice/InternalFragmentation
555555557000-555555558000 r--p 00002000 08:01 1966744 /home/AB1/ProgPractice/InternalFragmentation
555555558000-555555559000 rw-p 00003000 08:01 1966744 /home/AB1/ProgPractice/InternalFragmentation
555555559000-55555557a000 rw-p 00000000 00:00 0 [heap]
7ffff7dd8000-7ffff7dfd000 r--p 00000000 08:01 2234184 /usr/lib/libc-2.30.so
7ffff7dfd000-7ffff7f4a000 r-xp 00025000 08:01 2234184 /usr/lib/libc-2.30.so
7ffff7f4a000-7ffff7f94000 r--p 00172000 08:01 2234184 /usr/lib/libc-2.30.so
7ffff7f94000-7ffff7f95000 ---p 001bc000 08:01 2234184 /usr/lib/libc-2.30.so
7ffff7f95000-7ffff7f98000 r--p 001bc000 08:01 2234184 /usr/lib/libc-2.30.so
7ffff7f98000-7ffff7f9b000 rw-p 001bf000 08:01 2234184 /usr/lib/libc-2.30.so
7ffff7f9b000-7ffff7fa1000 rw-p 00000000 00:00 0
7ffff7fce000-7ffff7fd1000 r--p 00000000 00:00 0 [vvar]
7ffff7fd1000-7ffff7fd2000 r-xp 00000000 00:00 0 [vdso]
7ffff7fd2000-7ffff7fd4000 r--p 00000000 08:01 2234140 /usr/lib/ld-2.30.so
7ffff7fd4000-7ffff7ff3000 r-xp 00002000 08:01 2234140 /usr/lib/ld-2.30.so
7ffff7ff3000-7ffff7ffb000 r--p 00021000 08:01 2234140 /usr/lib/ld-2.30.so
7ffff7ffc000-7ffff7ffd000 r--p 00029000 08:01 2234140 /usr/lib/ld-2.30.so
7ffff7ffd000-7ffff7ffe000 rw-p 0002a000 08:01 2234140 /usr/lib/ld-2.30.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]
I've disabled ASLR but it doesn't make a difference. Any suggestions

Related

Why is the heap section present when there are no malloc used

I am trying to find out whether heap exists in the address space of the process, if we don't call malloc.
#include <stdio.h>
int main()
{
getchar();
return 0;
}
Heap section is present in the maps even if i dont call malloc
cat /proc/73268/maps
55d0b405c000-55d0b4160000 r-xp 00000000 08:01 5505031 /bin/bash
55d0b435f000-55d0b4363000 r--p 00103000 08:01 5505031 /bin/bash
55d0b4363000-55d0b436c000 rw-p 00107000 08:01 5505031 /bin/bash
55d0b436c000-55d0b4376000 rw-p 00000000 00:00 0
55d0b567e000-55d0b5815000 rw-p 00000000 00:00 0 [heap]
7f57533fd000-7f5753408000 r-xp 00000000 08:01 2102129 /lib/x86_64-linux-gnu/libnss_files-2.27.so
7f5753408000-7f5753607000 ---p 0000b000 08:01 2102129 /lib/x86_64-linux-gnu/libnss_files-2.27.so
7f5753607000-7f5753608000 r--p 0000a000 08:01 2102129 /lib/x86_64-linux-gnu/libnss_files-2.27.so
7f5753608000-7f5753609000 rw-p 0000b000 08:01 2102129 /lib/x86_64-linux-gnu/libnss_files-2.27.so
7f5753609000-7f575360f000 rw-p 00000000 00:00 0
7f575360f000-7f5753626000 r-xp 00000000 08:01 2102123 /lib/x86_64-linux-gnu/libnsl-2.27.so
7f5753626000-7f5753825000 ---p 00017000 08:01 2102123 /lib/x86_64-linux-gnu/libnsl-2.27.so
7f5753825000-7f5753826000 r--p 00016000 08:01 2102123 /lib/x86_64-linux-gnu/libnsl-2.27.so
7f5753826000-7f5753827000 rw-p 00017000 08:01 2102123 /lib/x86_64-linux-gnu/libnsl-2.27.so
7f5753827000-7f5753829000 rw-p 00000000 00:00 0
7f5753829000-7f5753834000 r-xp 00000000 08:01 2102140 /lib/x86_64-linux-gnu/libnss_nis-2.27.so
7f5753834000-7f5753a33000 ---p 0000b000 08:01 2102140 /lib/x86_64-linux-gnu/libnss_nis-2.27.so
7f5753a33000-7f5753a34000 r--p 0000a000 08:01 2102140 /lib/x86_64-linux-gnu/libnss_nis-2.27.so
7f5753a34000-7f5753a35000 rw-p 0000b000 08:01 2102140 /lib/x86_64-linux-gnu/libnss_nis-2.27.so
7f5753a35000-7f5753a3d000 r-xp 00000000 08:01 2102125 /lib/x86_64-linux-gnu/libnss_compat-2.27.so
7f5753a3d000-7f5753c3d000 ---p 00008000 08:01 2102125 /lib/x86_64-linux-gnu/libnss_compat-2.27.so
7f5753c3d000-7f5753c3e000 r--p 00008000 08:01 2102125 /lib/x86_64-linux-gnu/libnss_compat-2.27.so
7f5753c3e000-7f5753c3f000 rw-p 00009000 08:01 2102125 /lib/x86_64-linux-gnu/libnss_compat-2.27.so
7f5753c3f000-7f575460e000 r--p 00000000 08:01 793285 /usr/lib/locale/locale-archive
7f575460e000-7f57547f5000 r-xp 00000000 08:01 2102039 /lib/x86_64-linux-gnu/libc-2.27.so
7f57547f5000-7f57549f5000 ---p 001e7000 08:01 2102039 /lib/x86_64-linux-gnu/libc-2.27.so
7f57549f5000-7f57549f9000 r--p 001e7000 08:01 2102039 /lib/x86_64-linux-gnu/libc-2.27.so
7f57549f9000-7f57549fb000 rw-p 001eb000 08:01 2102039 /lib/x86_64-linux-gnu/libc-2.27.so
7f57549fb000-7f57549ff000 rw-p 00000000 00:00 0
7f57549ff000-7f5754a02000 r-xp 00000000 08:01 2102062 /lib/x86_64-linux-gnu/libdl-2.27.so
7f5754a02000-7f5754c01000 ---p 00003000 08:01 2102062 /lib/x86_64-linux-gnu/libdl-2.27.so
7f5754c01000-7f5754c02000 r--p 00002000 08:01 2102062 /lib/x86_64-linux-gnu/libdl-2.27.so
7f5754c02000-7f5754c03000 rw-p 00003000 08:01 2102062 /lib/x86_64-linux-gnu/libdl-2.27.so
7f5754c03000-7f5754c28000 r-xp 00000000 08:01 2102197 /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f5754c28000-7f5754e28000 ---p 00025000 08:01 2102197 /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f5754e28000-7f5754e2c000 r--p 00025000 08:01 2102197 /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f5754e2c000-7f5754e2d000 rw-p 00029000 08:01 2102197 /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f5754e2d000-7f5754e54000 r-xp 00000000 08:01 2102011 /lib/x86_64-linux-gnu/ld-2.27.so
7f5754fb6000-7f575503c000 rw-p 00000000 00:00 0
7f575504d000-7f5755054000 r--s 00000000 08:01 1050910 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
7f5755054000-7f5755055000 r--p 00027000 08:01 2102011 /lib/x86_64-linux-gnu/ld-2.27.so
7f5755055000-7f5755056000 rw-p 00028000 08:01 2102011 /lib/x86_64-linux-gnu/ld-2.27.so
7f5755056000-7f5755057000 rw-p 00000000 00:00 0
7ffd41cc9000-7ffd41cea000 rw-p 00000000 00:00 0 [stack]
7ffd41db7000-7ffd41dba000 r--p 00000000 00:00 0 [vvar]
7ffd41dba000-7ffd41dbc000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
I tried this on Ubuntu 18.04 and gcc version is 7.4.0, can you guys help me understand why is the heap section created even if we dont have any malloc.
try this
int main()
{
for(;;);
}
And compile it with gcc test.c -nodefaultlibs -Wl,-e,main -o test -nostdlib -static
Your program is using malloc(), at least when using the standard glibc from your system:
$ cat failmalloc.c
#include <unistd.h>
#define MSG "out of memory!\n"
void *malloc(size_t z){
write(2, MSG, sizeof MSG - 1); _exit(13);
}
$ cc -Wall -shared failmalloc.c -o failmalloc.so
$ LD_PRELOAD=./failmalloc.so ./your_program
out of memory!
Also, there's no guarantee that malloc() will be using the "heap". There are malloc() implementations based exclusively on mmap(2).

C: sbrk() addresses ascending or descending?

When sbrk() returns a pointer to an address that is the beginning of the heap, are the addresses ascending or descending? For example, if I had a 10 byte heap from addresses 1 to 10, would sbrk() return a pointer to address 10 or 1?
On a similar note, heap addresses tend to grow "down"... but how can I figure out whether the addresses increase or decrease on my computer?
The man page on Mac OS X says:
The brk and sbrk functions are historical curiosities left over from earlier days before the
advent of virtual memory management.
The current value of the program break is reliably returned by sbrk(0).
The sbrk function returns a pointer to the base of the
new storage if successful; otherwise -1 with errno set to indicate why the allocation failed.
Suppose you use:
void *base = sbrk(1024);
After that, assuming no error, base will contain the starting address of a 1024 byte (minimum) block of memory; (char *)base + 1024 will be beyond what you requested, though it may still be valid since the page size may be larger than 1024.
It doesn't say directly whether a subsequent allocation will have a larger or smaller address than another. However, it is likely to be in increasing order of addresses.
The brk() function sets the break or lowest address of a
process's data segment (uninitialized data) to addr (immediately above bss). Data addressing
is restricted between addr and the lowest stack pointer to the stack segment. Memory is allocated by brk in page size pieces; if addr is not evenly divisible by the system page size, it
is increased to the next page boundary.
This implies that the extra space is after the data and bss segments, and grows up towards the stack (which grows downwards in memory). However, relying on that would probably be foolhardy. You'd do best to use sbrk(0) to establish the current end after calling sbrk(extra) to get extra space; this will tell you what you really got and the two addresses tell you where it was made available.
If you are on Linux, you can examine /proc/$PID/maps to see how the virtual address space is utilized for each process.
Sample code: mappingTest.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int foo(int depth) {
char buf[8192];
if (0 == depth)
printf("%p\n", buf);
if (1000 < depth) {
printf("%p\n", buf);
return getchar();
} else {
return 1 + foo(depth + 1);
}
}
int main() {
const size_t SIZE = 1000 * 1000 * 1000;
getchar();
char * const p = malloc(SIZE);
printf("%p\n", p);
getchar();
free(p);
getchar();
foo(0);
return 0;
}
Note: char buf[8192] and recursion of 1000 times assume that the maximum stack size is 8 MB (you can confirm with ulimit -s.)
$ gcc mappingTest.c -o mappingTest -Wall -Wextra -Wno-missing-field-initializers -std=c89 -O0 -g3 && echo OK
OK
$ ./mappingTest
At the 1st getchar(), we see the following memory mappings for the process:
$ cat /proc/`pidof mappingTest`/maps
00400000-00401000 r-xp 00000000 08:05 21687266 /home/nodakai/prog/exp/mappingTest
00600000-00601000 r--p 00000000 08:05 21687266 /home/nodakai/prog/exp/mappingTest
00601000-00602000 rw-p 00001000 08:05 21687266 /home/nodakai/prog/exp/mappingTest
7f2e96e8a000-7f2e9703f000 r-xp 00000000 08:05 14314431 /lib/x86_64-linux-gnu/libc-2.15.so
7f2e9703f000-7f2e9723f000 ---p 001b5000 08:05 14314431 /lib/x86_64-linux-gnu/libc-2.15.so
7f2e9723f000-7f2e97243000 r--p 001b5000 08:05 14314431 /lib/x86_64-linux-gnu/libc-2.15.so
7f2e97243000-7f2e97245000 rw-p 001b9000 08:05 14314431 /lib/x86_64-linux-gnu/libc-2.15.so
7f2e97245000-7f2e9724a000 rw-p 00000000 00:00 0
7f2e9724a000-7f2e9726c000 r-xp 00000000 08:05 14314443 /lib/x86_64-linux-gnu/ld-2.15.so
7f2e97443000-7f2e97446000 rw-p 00000000 00:00 0
7f2e97469000-7f2e9746c000 rw-p 00000000 00:00 0
7f2e9746c000-7f2e9746d000 r--p 00022000 08:05 14314443 /lib/x86_64-linux-gnu/ld-2.15.so
7f2e9746d000-7f2e9746f000 rw-p 00023000 08:05 14314443 /lib/x86_64-linux-gnu/ld-2.15.so
7fffa6d43000-7fffa6d64000 rw-p 00000000 00:00 0 [stack]
7fffa6dff000-7fffa6e00000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
We hit Enter and proceed to the 2nd getchar().
I got 0x7f2e5b4dd010 on my terminal as the value of p and it falls within the first anonymous mapping region 7f2e5b4dd000-7f2e96e8a000 in the below listing, but it didin't exist in the above listing.
$ cat /proc/`pidof mappingTest`/maps
00400000-00401000 r-xp 00000000 08:05 21687266 /home/nodakai/prog/exp/mappingTest
00600000-00601000 r--p 00000000 08:05 21687266 /home/nodakai/prog/exp/mappingTest
00601000-00602000 rw-p 00001000 08:05 21687266 /home/nodakai/prog/exp/mappingTest
7f2e5b4dd000-7f2e96e8a000 rw-p 00000000 00:00 0
7f2e96e8a000-7f2e9703f000 r-xp 00000000 08:05 14314431 /lib/x86_64-linux-gnu/libc-2.15.so
7f2e9703f000-7f2e9723f000 ---p 001b5000 08:05 14314431 /lib/x86_64-linux-gnu/libc-2.15.so
7f2e9723f000-7f2e97243000 r--p 001b5000 08:05 14314431 /lib/x86_64-linux-gnu/libc-2.15.so
7f2e97243000-7f2e97245000 rw-p 001b9000 08:05 14314431 /lib/x86_64-linux-gnu/libc-2.15.so
7f2e97245000-7f2e9724a000 rw-p 00000000 00:00 0
7f2e9724a000-7f2e9726c000 r-xp 00000000 08:05 14314443 /lib/x86_64-linux-gnu/ld-2.15.so
7f2e97443000-7f2e97446000 rw-p 00000000 00:00 0
7f2e97468000-7f2e9746c000 rw-p 00000000 00:00 0
7f2e9746c000-7f2e9746d000 r--p 00022000 08:05 14314443 /lib/x86_64-linux-gnu/ld-2.15.so
7f2e9746d000-7f2e9746f000 rw-p 00023000 08:05 14314443 /lib/x86_64-linux-gnu/ld-2.15.so
7fffa6d43000-7fffa6d64000 rw-p 00000000 00:00 0 [stack]
7fffa6dff000-7fffa6e00000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
We hit Enter and proceed to the 3rd getchar().
In the below listing, we see the anonymous mapping region disappeared due to free().
$ cat /proc/`pidof mappingTest`/maps
00400000-00401000 r-xp 00000000 08:05 21687266 /home/nodakai/prog/exp/mappingTest
00600000-00601000 r--p 00000000 08:05 21687266 /home/nodakai/prog/exp/mappingTest
00601000-00602000 rw-p 00001000 08:05 21687266 /home/nodakai/prog/exp/mappingTest
7f2e96e8a000-7f2e9703f000 r-xp 00000000 08:05 14314431 /lib/x86_64-linux-gnu/libc-2.15.so
7f2e9703f000-7f2e9723f000 ---p 001b5000 08:05 14314431 /lib/x86_64-linux-gnu/libc-2.15.so
7f2e9723f000-7f2e97243000 r--p 001b5000 08:05 14314431 /lib/x86_64-linux-gnu/libc-2.15.so
7f2e97243000-7f2e97245000 rw-p 001b9000 08:05 14314431 /lib/x86_64-linux-gnu/libc-2.15.so
7f2e97245000-7f2e9724a000 rw-p 00000000 00:00 0
7f2e9724a000-7f2e9726c000 r-xp 00000000 08:05 14314443 /lib/x86_64-linux-gnu/ld-2.15.so
7f2e97443000-7f2e97446000 rw-p 00000000 00:00 0
7f2e97468000-7f2e9746c000 rw-p 00000000 00:00 0
7f2e9746c000-7f2e9746d000 r--p 00022000 08:05 14314443 /lib/x86_64-linux-gnu/ld-2.15.so
7f2e9746d000-7f2e9746f000 rw-p 00023000 08:05 14314443 /lib/x86_64-linux-gnu/ld-2.15.so
7fffa6d43000-7fffa6d64000 rw-p 00000000 00:00 0 [stack]
7fffa6dff000-7fffa6e00000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
We hit Enter and proceed to the 4th getchar() in the deeply nested calls of foo().
I got 0x7fffa6d60ba0 and 0x7fffa6582ff0 on my terminal as the addresses of buf in the 1st and 1001st recursive call of foo(). Both of them fall within the [stack] region (7fffa6582000-7fffa6d64000; 0x7e2000 == 8 MB) now. But note that it was previously 7fffa6d43000-7fffa6d64000; 0x21000 == 132 KB.
$ cat /proc/`pidof mappingTest`/maps
00400000-00401000 r-xp 00000000 08:05 21687266 /home/nodakai/prog/exp/mappingTest
00600000-00601000 r--p 00000000 08:05 21687266 /home/nodakai/prog/exp/mappingTest
00601000-00602000 rw-p 00001000 08:05 21687266 /home/nodakai/prog/exp/mappingTest
7f2e96e8a000-7f2e9703f000 r-xp 00000000 08:05 14314431 /lib/x86_64-linux-gnu/libc-2.15.so
7f2e9703f000-7f2e9723f000 ---p 001b5000 08:05 14314431 /lib/x86_64-linux-gnu/libc-2.15.so
7f2e9723f000-7f2e97243000 r--p 001b5000 08:05 14314431 /lib/x86_64-linux-gnu/libc-2.15.so
7f2e97243000-7f2e97245000 rw-p 001b9000 08:05 14314431 /lib/x86_64-linux-gnu/libc-2.15.so
7f2e97245000-7f2e9724a000 rw-p 00000000 00:00 0
7f2e9724a000-7f2e9726c000 r-xp 00000000 08:05 14314443 /lib/x86_64-linux-gnu/ld-2.15.so
7f2e97443000-7f2e97446000 rw-p 00000000 00:00 0
7f2e97468000-7f2e9746c000 rw-p 00000000 00:00 0
7f2e9746c000-7f2e9746d000 r--p 00022000 08:05 14314443 /lib/x86_64-linux-gnu/ld-2.15.so
7f2e9746d000-7f2e9746f000 rw-p 00023000 08:05 14314443 /lib/x86_64-linux-gnu/ld-2.15.so
7fffa6582000-7fffa6d64000 rw-p 00000000 00:00 0 [stack]
7fffa6dff000-7fffa6e00000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
You may have more fun with inline assembly like this:
#define PEEK_ESP(reg) \
__asm__ __volatile__ ( \
"movq %%rsp, %0" \
: "=r"(reg) \
)
...
void *p;
PEEK_ESP(p);

Where is the dynamic library actually in the memory? [duplicate]

This question already has answers here:
When / How does Linux load shared libraries into address space?
(5 answers)
Closed 9 years ago.
On linux platform,
Could anyone tell me where is the dynamic library in the memory?
I learned that the dynamic library are mmap to the process according to the GOT
of this process,
is that true?
Thank you!
You can see where things got mapped in a Linux process by looking in /proc/pid/maps -- all you need to know is the process id. For example:
$ cat /proc/self/maps
00400000-0040b000 r-xp 00000000 08:01 71827604 /bin/cat
0060a000-0060b000 r--p 0000a000 08:01 71827604 /bin/cat
0060b000-0060c000 rw-p 0000b000 08:01 71827604 /bin/cat
00690000-006b1000 rw-p 00000000 00:00 0 [heap]
7f07fbaf7000-7f07fbdc0000 r--p 00000000 08:01 18094104 /usr/lib/locale/locale-archive
7f07fbdc0000-7f07fbf75000 r-xp 00000000 08:01 14552996 /lib/x86_64-linux-gnu/libc-2.15.so
7f07fbf75000-7f07fc175000 ---p 001b5000 08:01 14552996 /lib/x86_64-linux-gnu/libc-2.15.so
7f07fc175000-7f07fc179000 r--p 001b5000 08:01 14552996 /lib/x86_64-linux-gnu/libc-2.15.so
7f07fc179000-7f07fc17b000 rw-p 001b9000 08:01 14552996 /lib/x86_64-linux-gnu/libc-2.15.so
7f07fc17b000-7f07fc180000 rw-p 00000000 00:00 0
7f07fc180000-7f07fc1a2000 r-xp 00000000 08:01 14553008 /lib/x86_64-linux-gnu/ld-2.15.so
7f07fc37e000-7f07fc381000 rw-p 00000000 00:00 0
7f07fc3a0000-7f07fc3a2000 rw-p 00000000 00:00 0
7f07fc3a2000-7f07fc3a3000 r--p 00022000 08:01 14553008 /lib/x86_64-linux-gnu/ld-2.15.so
7f07fc3a3000-7f07fc3a5000 rw-p 00023000 08:01 14553008 /lib/x86_64-linux-gnu/ld-2.15.so
7fff90e28000-7fff90e49000 rw-p 00000000 00:00 0 [stack]
7fff90f1f000-7fff90f20000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
shows everything that got mapped in to run the cat program.

Non-existent physical address error with mmap

I'm trying to mmap a file, and it seems to succeed but when I access it, I get an SIGBUS error.
Code:
int main(int argc, char* argv[]) {
int pid = getpid();
char cmd [1024];
int file;
if (argc != 2) {
printf("Wrong arguments\n");
return 1;
}
printf("%s", argv[1]);
int numpages = atoi(argv[1]);
sprintf(cmd, "cat /proc/%d/maps", pid);
system(cmd);
long page_size = sysconf(_SC_PAGESIZE);
file = open(argv[1], O_RDWR, (mode_t)0600);
ftruncate(file, page_size * numpages);
if(file == -1) {
perror("file open failed!\n");
return 1;
}
printf("\n\n mapping file - numpages: %d \n\n", numpages);
printf("mapping %ld KB\n", page_size * numpages/1024);
int* mapped_file = mmap(0, page_size * numpages, PROT_READ | PROT_WRITE, MAP_PRIVATE, file, 0 );
if (mapped_file == MAP_FAILED) {
perror("Map failed");
return 1;
}
printf("mapped file at %p\n\n", mapped_file);
int* current_pos = mapped_file;
system(cmd);
int j;
for (j=0; j<numpages; j++) {
printf("%d ", *current_pos);
current_pos += page_size/4;
}
if (munmap (mapped_file, page_size * numpages) == -1) {
perror ("munmap");
return 1;
}
if (close(file) == -1) {
perror("close");
return 1;
}
return 0;
}
Output:
(gdb) run 64
Starting program: /home/jords/engcode/workspace/SE370Assignment3/A3Program3 64
00400000-00401000 r-xp 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
00600000-00601000 r--p 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
00601000-00602000 rw-p 00001000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
7ffff7a48000-7ffff7bd2000 r-xp 00000000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7bd2000-7ffff7dd1000 ---p 0018a000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd1000-7ffff7dd5000 r--p 00189000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd5000-7ffff7dd6000 rw-p 0018d000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd6000-7ffff7ddc000 rw-p 00000000 00:00 0
7ffff7ddc000-7ffff7dfd000 r-xp 00000000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffff7fd0000-7ffff7fd3000 rw-p 00000000 00:00 0
7ffff7ff8000-7ffff7ffb000 rw-p 00000000 00:00 0
7ffff7ffb000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00020000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffff7ffd000-7ffff7fff000 rw-p 00021000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
64
mapping file - numpages: 64
mapping 256 KB
mapped file at 0x7ffff7ff4000
00400000-00401000 r-xp 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
00600000-00601000 r--p 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
00601000-00602000 rw-p 00001000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
7ffff7a48000-7ffff7bd2000 r-xp 00000000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7bd2000-7ffff7dd1000 ---p 0018a000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd1000-7ffff7dd5000 r--p 00189000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd5000-7ffff7dd6000 rw-p 0018d000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7ffff7dd6000-7ffff7ddc000 rw-p 00000000 00:00 0
7ffff7ddc000-7ffff7dfd000 r-xp 00000000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffff7fd0000-7ffff7fd3000 rw-p 00000000 00:00 0
7ffff7ff4000-7ffff7ff8000 rw-p 00000000 08:03 3288973 /home/jords/engcode/workspace/SE370Assignment3/64
7ffff7ff8000-7ffff7ffb000 rw-p 00000000 00:00 0
7ffff7ffb000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00020000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffff7ffd000-7ffff7fff000 rw-p 00021000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Program received signal SIGBUS, Bus error.
0x0000000000400abb in main (argc=2, argv=0x7fffffffe058) at A3Program3.c:49
49 printf("%d", mapped_file[0]);
(gdb)
It's confusing me, since you can clearly see in the maps output that the file has been mapped and the address is correct - but it gives an error whenever I try to access it.
EDIT: Valgrind:
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
==16295==
==16295== Process terminating with default action of signal 7 (SIGBUS)
==16295== Non-existent physical address at address 0x4024000
==16295== at 0x400AB7: main (A3Program3.c:49)
==16295==
Update: So I have stopped it crashing now (thanks :)) with the ftruncate call, but it's printing all zeros:
jords#jords-desktop ~/engcode/workspace/SE370Assignment3 (master) $ ./A3Program3 64
00400000-00401000 r-xp 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
00600000-00601000 r--p 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
00601000-00602000 rw-p 00001000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
7f96ec7a1000-7f96ec92b000 r-xp 00000000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7f96ec92b000-7f96ecb2a000 ---p 0018a000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7f96ecb2a000-7f96ecb2e000 r--p 00189000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7f96ecb2e000-7f96ecb2f000 rw-p 0018d000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7f96ecb2f000-7f96ecb35000 rw-p 00000000 00:00 0
7f96ecb35000-7f96ecb56000 r-xp 00000000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7f96ecd2a000-7f96ecd2d000 rw-p 00000000 00:00 0
7f96ecd52000-7f96ecd55000 rw-p 00000000 00:00 0
7f96ecd55000-7f96ecd56000 r--p 00020000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7f96ecd56000-7f96ecd58000 rw-p 00021000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7fff9be10000-7fff9be31000 rw-p 00000000 00:00 0 [stack]
7fff9bf0b000-7fff9bf0c000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
64
mapping file - numpages: 64
mapping 256 KB
mapped file at 0x7f96eccea000
00400000-00401000 r-xp 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
00600000-00601000 r--p 00000000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
00601000-00602000 rw-p 00001000 08:03 3288976 /home/jords/engcode/workspace/SE370Assignment3/A3Program3
7f96ec7a1000-7f96ec92b000 r-xp 00000000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7f96ec92b000-7f96ecb2a000 ---p 0018a000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7f96ecb2a000-7f96ecb2e000 r--p 00189000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7f96ecb2e000-7f96ecb2f000 rw-p 0018d000 00:10 8103 /lib/x86_64-linux-gnu/libc-2.13.so
7f96ecb2f000-7f96ecb35000 rw-p 00000000 00:00 0
7f96ecb35000-7f96ecb56000 r-xp 00000000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7f96eccea000-7f96ecd2a000 rw-p 00000000 08:03 3288973 /home/jords/engcode/workspace/SE370Assignment3/64
7f96ecd2a000-7f96ecd2d000 rw-p 00000000 00:00 0
7f96ecd52000-7f96ecd55000 rw-p 00000000 00:00 0
7f96ecd55000-7f96ecd56000 r--p 00020000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7f96ecd56000-7f96ecd58000 rw-p 00021000 00:10 8090 /lib/x86_64-linux-gnu/ld-2.13.so
7fff9be10000-7fff9be31000 rw-p 00000000 00:00 0 [stack]
7fff9bf0b000-7fff9bf0c000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
I think this is because the file is not being read correctly, so all I'm reading is padded zeros. But I'm not sure why that would be
Update, worked it out, it was actually reading the file correctly I was just making a mistake in terms of how to read it. Thanks everyone
The problem is that you open the file with O_TRUNC which truncates it, and since mmap can only map the existing contents of a file it will give you a sigbus. Use truncate() (and friends) to truncate the file to the correct size before mapping it.
From mmap's man page:
SIGBUS Attempted access to a portion of the buffer that does not correspond to the file (for example, beyond the end of the file, including the case where another process has truncated the file).
There's a bug, but it won't explain the crash in mapped_file[0].
sysconf(_SC_PAGESIZE) gives you the page size in bytes.
At each iteration of current_pos += page_size you're incrementing your pointer by sysconf(_SC_PAGESIZE)*sizeof(int) so you quickly get outside the mapped region.
Also, the page_size * 4 in mmap looks questionable: surely num_pages ought to come into the equation?

Stack Overflow problem in a recursive program in C

I am getting a stack overflow in one of the recursive functions i am running..
Here is the code..
void* buddyMalloc(int req_size)
{
// Do something here
return buddy_findout(original_index,req_size); // This is the recursive call
}
void *buddy_findout(int current_index,int req_size)
{
char *selected = NULL;
if(front!=NULL)
{
if(current_index==original_index)
{
// Do something here
return selected;
}
else
{
// Do Something here
return buddy_findout(current_index+1,req_size);
}
}
else
{
return buddy_findout(current_index-1,req_size);
}
}
Consider the initial value of index to be 4. and it first do index-1 till it reaches 0 index. and then it comes back to index 4 by incrementing..This is wht i want to implement.
But it gives a stack overflow with memory map in the command prompt :
Here is the output from my shell :
*** glibc detected *** ./473_mem: free(): invalid pointer: 0x00c274c0 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb50ff1]
/lib/tls/i686/cmov/libc.so.6[0xb526f2]
/lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0xb557cd]
./473_mem[0x8048b44]
./473_mem[0x8048b74]
./473_mem[0x8048b74]
./473_mem[0x8048944]
./473_mem[0x8048c87]
./473_mem[0x8048d31]
./473_mem[0x8048f79]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xafcb56]
./473_mem[0x8048671]
======= Memory map: ========
0017c000-00198000 r-xp 00000000 08:01 5224 /lib/libgcc_s.so.1
00198000-00199000 r--p 0001b000 08:01 5224 /lib/libgcc_s.so.1
00199000-0019a000 rw-p 0001c000 08:01 5224 /lib/libgcc_s.so.1
00260000-00284000 r-xp 00000000 08:01 1927 /lib/tls/i686/cmov/libm-2.10.1.so
00284000-00285000 r--p 00023000 08:01 1927 /lib/tls/i686/cmov/libm-2.10.1.so
00285000-00286000 rw-p 00024000 08:01 1927 /lib/tls/i686/cmov/libm-2.10.1.so
006cd000-006e8000 r-xp 00000000 08:01 6662 /lib/ld-2.10.1.so
006e8000-006e9000 r--p 0001a000 08:01 6662 /lib/ld-2.10.1.so
006e9000-006ea000 rw-p 0001b000 08:01 6662 /lib/ld-2.10.1.so
00aa9000-00aaa000 r-xp 00000000 00:00 0 [vdso]
00ae6000-00c24000 r-xp 00000000 08:01 1900 /lib/tls/i686/cmov/libc-2.10.1.so
00c24000-00c25000 ---p 0013e000 08:01 1900 /lib/tls/i686/cmov/libc-2.10.1.so
00c25000-00c27000 r--p 0013e000 08:01 1900 /lib/tls/i686/cmov/libc-2.10.1.so
00c27000-00c28000 rw-p 00140000 08:01 1900 /lib/tls/i686/cmov/libc-2.10.1.so
00c28000-00c2b000 rw-p 00000000 00:00 0
08048000-0804a000 r-xp 00000000 00:14 2176 /media/windows-share/OS/Project2/473_mem
0804a000-0804b000 r--p 00001000 00:14 2176 /media/windows-share/OS/Project2/473_mem
0804b000-0804c000 rw-p 00002000 00:14 2176 /media/windows-share/OS/Project2/473_mem
08483000-084a4000 rw-p 00000000 00:00 0 [heap]
b7600000-b7621000 rw-p 00000000 00:00 0
b7621000-b7700000 ---p 00000000 00:00 0
b7716000-b7819000 rw-p 00000000 00:00 0
b7827000-b782a000 rw-p 00000000 00:00 0
bfb96000-bfbab000 rw-p 00000000 00:00 0 [stack]
Aborted
Thanks in advance
adi
Look at your compiler docs to see if it has "tail recursion" optimization.
(Though now your stack overflow problem becomes an infinite loop problem!)
gcc -foptimize-sibling-calls ...
Where is front set?
In call:
else
{
return buddy_findout(current_index-1,req_size);
}
}
When front is NULL You just come back to same function with smaller current_index and keep looping and looping. There's no stop condition for current_index == 0

Resources