0

Note: sys_brk returns the program break while brk() returns 0 or -1.(According to manual brk(2), NOTES)

The following code can pass.

#include <unistd.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <string.h>
#include <stdint.h>

int main (void)
{
    long beg_break = syscall (SYS_brk, 0);//get current program break.
    
    long mid_break =  syscall (SYS_brk, beg_break + 100);
    
    long end_break = syscall (SYS_brk, beg_break);//set the program break back
}

But there will be a segmentation fault at the line syscall (SYS_brk, beg_break) if I try to print them:

( My question is at the end.)

long beg_break = syscall (SYS_brk, 0);
printf ("%#lX\n", beg_break);

long mid_break =  syscall (SYS_brk, beg_break + 100);
printf ("%#lX\n", mid_break);

long end_break = syscall (SYS_brk, beg_break);
printf ("%#lX\n", end_break);

Output:

0X557E46CDE000
0X557E46CDE064
Segementation fault

It's not accendital, I have tried many times on different PCs, also the experiments below:

  1. using stderr instead of stdout, it works.
long beg_break = syscall (SYS_brk, 0);
fprintf (stderr, "%#lX\n", beg_break);

long new_break =  syscall (SYS_brk, beg_break + 100);
fprintf (stderr, "%#lX\n", new_break);

long end_break = syscall (SYS_brk, beg_break);
fprintf (stderr, "%#lX\n", end_break);
  1. not using printf() between brk(), it works.
long beg_break = syscall (SYS_brk, 0);
long mid_break =  syscall (SYS_brk, beg_break + 100);
long end_break = syscall (SYS_brk, beg_break);

printf ("%#lX\n", beg_break);
printf ("%#lX\n", mid_break);
printf ("%#lX\n", end_break);
  1. disable buffering of stdout, it works.
setvbuf (stdout, NULL, _IONBF, 0);
long beg_break = syscall (SYS_brk, 0);
printf ("%#lX\n", beg_break);

long mid_break =  syscall (SYS_brk, beg_break + 100);
printf ("%#lX\n", mid_break);

long end_break = syscall (SYS_brk, beg_break);
printf ("%#lX\n", end_break);

So I guess it results from printf() calling malloc(), which bases on brk():

long beg = syscall (SYS_brk, 0);
printf ("hello world %d\n", 123);
long end = syscall (SYS_brk, 0);

printf ("%#lX\n", beg);
printf ("%#lX\n", end);

The output:

hello world 123
0X56501B6F0000
0X56501B711000

It seems that I should avoid using C library with brk():

Since brk() doesn't write/read the memory on heap, why brk(), instead of printf(), results in the segmentation fault ?

barbyQAQ
  • 45
  • 5
  • 1
    Why don't you use [`sbrk`](https://man7.org/linux/man-pages/man2/sbrk.2.html) instead? – Some programmer dude Jul 01 '23 at 22:37
  • Also, what is the actual and original problem you need to solve? What is the reason you want to use `sbrk`? What problem is it supposed to solve? You are aware of that it has been marked as legacy and doesn't even exist in POSIX? – Some programmer dude Jul 01 '23 at 22:39
  • 5
    Per the [Linux `brk()` man page](https://man7.org/linux/man-pages/man2/brk.2.html#NOTES): "Avoid using `brk()` and `sbrk()`: the `malloc(3)` memory allocation package is the portable and comfortable way of allocating memory." And see [**In malloc, why use brk at all? Why not just use mmap?**](https://stackoverflow.com/questions/55768549/in-malloc-why-use-brk-at-all-why-not-just-use-mmap). Note what that title states: `malloc()` uses `[s]brk()` internally for heap memory. When you call `brk()`, you, umm, *break* `malloc()`. And `printf()` uses `malloc()` internally... – Andrew Henle Jul 01 '23 at 22:57
  • I will bet a cookie. that it's actually crashing on the third call to printf. Printf may (but is not required to) call malloc internally. – zwol Jul 02 '23 at 02:22
  • @Someprogrammerdude I'm tring to control another process by `ptrace()`. It's easy to invoke system call. But I'm not sure about C library. – barbyQAQ Jul 02 '23 at 08:05
  • @AndrewHenle I'm trying to control another to allocate memory by `ptrace()`. I don't how to invoke `malloc()` or `sbrk()` by `ptrace()`, because they are not system calls. – barbyQAQ Jul 02 '23 at 08:07
  • @AndrewHenle It seems that `mmap()` is more complex than `brk()`. So I haven't tried it. – barbyQAQ Jul 02 '23 at 08:09
  • `ptrace` exists for debuggers and *only* for debuggers. Are you writing a debugger? – zwol Jul 04 '23 at 03:20
  • @zwol I use it to Intercept system calls. – barbyQAQ Jul 04 '23 at 06:02
  • @barbyQAQ That is not an answer to the question I asked you. – zwol Jul 04 '23 at 15:22

0 Answers0