LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   program break issue with brk system call (https://www.linuxquestions.org/questions/linux-software-2/program-break-issue-with-brk-system-call-4175555184/)

gopikrishna mogasati 10-03-2015 09:37 AM

program break issue with brk system call
 
Hi All ,

Please find the code and its output below ,I find a problem with brk ,

Please guide to solve this issue ,I am using this on x86/ubuntu machine.

#include<stdio.h>
#include<unistd.h>
extern char end,edata;
int a=0xa;
main()
{

printf("%p\n",&a);
printf("end of initialized data: %p\n",&edata);
printf("program break:%p\n",&end);
printf("pagesize=%ld\n",sysconf(_SC_PAGESIZE));
if(!brk(&end+4096))
printf("brk is successfull ie.,returned zero\n");
int *p=(int *)&end;
printf("start of heap:%p\n",p);
*p=4;
printf("%d\n",*p);
printf("program break now is :%p\n",sbrk(0));
}

Below are the instances of executable run twice simultaneously :
mgk@embeddedOS:~$ ./test
0x601060
end of initialized data: 0x601064
program break:0x601068
pagesize=4096
brk is successfull ie.,returned zero
start of heap:0x601068
4
program break now is :0x16b2000
mgk@embeddedOS:~$ ./test
0x601060
end of initialized data: 0x601064
program break:0x601068
pagesize=4096
brk is successfull ie.,returned zero
start of heap:0x601068
4
program break now is :0x1ab3000
mgk@embeddedOS:~$

My question is I am expecting program break should be at :0x602060 (0x601068+4096 bytes ) ,But it is not the expected value and even it is
changing for multiple instances.

This is different from what manual page says about brk and sbrk.Please let me know why is this so?what is influencing the expected output.

More over after tideous work I have come to narrow down the cause from manual pages as it says :
brk( ) is non portable one and not advisable to use .I have also used feature test macros but unsuccessful as suggested by manpages but still
unsuccessful.

Please guide me how can I make brk call work for me ,as what I am expecting.What extra care shall I take in compiling My code .

I am using x86,ubuntu platform .

Thanking ,
Gopikrishna .

berndbausch 10-04-2015 10:00 PM

I have the feeling that brk() returns zero no matter what crazy value you give it. Try brk(0); on my Centos 7 this is successful.

gopikrishna mogasati 10-04-2015 11:57 PM

program break issue with brk system call
 
Hi berndbausch ,

I am not getting any desired output ,Please let me know how to make this code portable/compatible
on My Ubuntu desktop machine .

berndbausch 10-06-2015 06:42 AM

What is the desired output?

gopikrishna mogasati 10-06-2015 06:50 AM

program break issue with brk system call
 
Hi berndbausch ,

My question is I am expecting program break should be at :0x602060 (0x601068+4096 bytes ) ,But it is not the expected value and even it is changing for multiple instances.

Hope you can find my code in this mail loop.

berndbausch 10-06-2015 07:15 AM

As I said, brk() seems to return success even if you give it nonsensical parameters like 0. I think that your call to brk doesn't succeed, even though it returns 0. Instead of brk, use sbrk.
I can't currently check this on Ubuntu though.

rtmistler 10-06-2015 07:33 AM

Please use [code] tags to surround your code. There are links in the FAQ and I also show a link in my signature to describe how to do this. It will be helpful to edit your original to fix that as well.

20+ years of Linux involvement and never encountered this library function.

What's the purpose of this exercise? I suspect homework.

I'm sure the compiler will accept what you've done, but declaring variables as extern and then not declaring them otherwise is then leaving it open to interpretation. I'm talking about where you declare end and edata as extern prior to the start of main(). Where were they declared otherwise.

What I see is that the compiler has placed the variable a at 0x601060, and the next two logical variables, end at 0x601068 and edata at 0x601064. This makes sense, it grows the heap in reverse. Since you didn't declare the external variables end and edata, it then makes them part of this program's heap.

A MORE IMPORTANT PROBLEM YOU NEED TO CONSIDER IS:
Code:

brk(&end+4096)
My interpretation of C operator precedence is that at Precedence Level 2, Unary Plus BEATS Address of. So my interpretation is that this is bug #2 in your code, bug #1 being that you auto-declared external variables. See C Operator Precedence.

You're next problem is that the address of the variable end is NOT going to change, therefore your validation attempt that the brk() call did something to change the location of that variable is an invalid assumption.

Take a further look at the function sbrk() which will return a pointer to the start of the newly allocated memory.

Now please explain what's wrong with using simple malloc() and free() and why this particular method of allocation and free is something you feel you need to do?

berndbausch 10-06-2015 08:44 AM

Quote:

Originally Posted by rtmistler (Post 5430686)
My interpretation of C operator precedence is that at Precedence Level 2, Unary Plus BEATS Address of.

Addition is in precedence group 3, the address operator in group 2. Unary plus is not the same as addition, so this part of the code is correct.
Quote:

Now please explain what's wrong with using simple malloc() and free() and why this particular method of allocation and free is something you feel you need to do?
Seconded.

gopikrishna mogasati 10-07-2015 11:47 AM

program break issue with brk system call
 
Hi rtmistler ,

As far as I know etext,edata,end are appended by linker script and more over man pages also describes about these variables
and how to use them , apart from these i don't have any other information regarding this variables .

As man pages say that &end is the start of heap ,Hence I used the same to check My brk call .

One thing I don't understand from the below code is even if brk is a failure/or not properly working my first sbrk(0) call should return same as &end ,which is the start of heap .But this also not the case I find .

#include<stdio.h>
#include<unistd.h>
extern char end,edata;
int a=0xa;
//int b;
//int c;
main()
{

printf("program break before brk() call is :%p\n",(void*)sbrk(0));
printf("%p\n",&a);
// printf("%p\n",&b);
// printf("%p\n",&c);
printf("end of initialized data: %p\n",&edata);
printf("program break:%p\n",&end);
printf("pagesize=%ld\n",sysconf(_SC_PAGESIZE));
if(!brk(&end+4096))
printf("brk is successfull ie.,returned zero\n");
int *p=(int *)&end;
printf("start of heap:%p\n",p);
*p=4;
printf("%d\n",*p);
printf("program break after brk() call is :%p\n",(void *)sbrk(0));
}

mgk@embeddedOS:~$ ./a.out
program break before sbrk() call is :0xdd2000
0x601060
end of initialized data: 0x601064
program break:0x601068
pagesize=4096
brk is successfull ie.,returned zero
start of heap:0x601068
4
program break after sbrk() call is :0xdd2000

The only thing I can suspect is the compatible library(glib c wrappers) version that this code has to be linked with
will lead to expected output .

gopikrishna mogasati 10-07-2015 11:52 AM

program break issue with brk system call
 
Hi berndbausch ,

You said my code worked in your CentOS machine , can you please let me know the glibc version of your system ,
So that I can link my code to that library version and check in My system .

rtmistler 10-07-2015 12:09 PM

My other point was that the address of "the variable" end is not going to change. It is going to stay where it is. Hence why I suggested sbrk so that you could obtain the "pointer to the start of the newly allocated memory" as the manual page states.

gopikrishna mogasati 10-07-2015 02:23 PM

program break issue with brk system call
 
Hi rtmistler ,

Can you please justify why sbrk(0) is not giving program break as end of uninitialized data(which is start of heap ),I am
providing this code which tried ,

#include<stdio.h>
#include<unistd.h>
extern char end;
int a;
main()
{

printf("program break:%p\n",(void*)sbrk(0));
printf("%p\n",&a);
printf("program break:%p\n",&end);

}

output :
mgk@embeddedOS:~$ ./a.out
program break:0x6ab000
0x60104c
program break:0x601050
mgk@embeddedOS:~$
mgk@embeddedOS:~$

Also find the .data section of objdump -D ./a.out

Disassembly of section .data:

0000000000601038 <__data_start>:
...

0000000000601040 <__dso_handle>:
...

Disassembly of section .bss:

0000000000601048 <__bss_start>:
601048: 00 00 add %al,(%rax)
...

000000000060104c <a>:
60104c: 00 00 add %al,(%rax)
...
This shows end of uninitialized data is (60104c+4)=601050 .which is equal to &end and that is the program break ,and beginning of heap .

If I perform sbrk(0) , why is it not giving me 601050 which is supposed to be the the return value of the current program break .

Please justify ??

More over multiple instances of same code gives different values for sbrk(0) .

mgk@embeddedOS:~$ ./a.out
program break:0xe65000
0x60104c
program break:0x601050
mgk@embeddedOS:~$ ./a.out
program break:0x20f3000
0x60104c
program break:0x601050
mgk@embeddedOS:~$ ./a.out
program break:0x24f5000
0x60104c
program break:0x601050
mgk@embeddedOS:~$

why is this so ??Any system wide influence ??Please suggest what improvements have to to done / Am I missing any basic fundamentals in using these calls ??
Thanking
Gopikrishna.

rtmistler 10-07-2015 02:30 PM

From the manual page:
Quote:

the program break is the first location after the end of the uninitialized data segment
Now, do a mathematical calculation and tell us what 0x60104c PLUS the size of an integer works out to be.

gopikrishna mogasati 10-07-2015 02:43 PM

program break issue with brk system call
 
Hi rtmistler,

yes it is the first location after the end of the uninitialized data section ,that is what I mean here ,What is the ambiguity
in my code's output ?

more over (0x60104c+0x4)=601050 right ??

Thanking ,
Gopikrishna .

berndbausch 10-07-2015 11:53 PM

Quote:

Originally Posted by gopikrishna mogasati (Post 5431313)
Hi berndbausch ,

You said my code worked in your CentOS machine , can you please let me know the glibc version of your system ,
So that I can link my code to that library version and check in My system .

I didn't say that your code worked on my system. In fact, the result is the same as on yours. What I said is that brk() returns 0 no matter what argument you pass it. Even brk(0) returns success.

To answer your question:

Code:

$ yum info glibc
(...)
Installed Packages
Name        : glibc
Arch        : x86_64
Version    : 2.17
Release    : 78.el7



All times are GMT -5. The time now is 05:33 PM.