Linux - SoftwareThis forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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 .
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.
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.
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?
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?
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 .
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 .
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 .
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.
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()
{
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.
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
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.