What's unsafe/legacy about brk/sbrk?What does the brk() system call do?How are sbrk/brk implemented in Linux?What do brk and sbrk stand for?What does the brk() system call do?using brk to get brk_startSbrk and negative parametersbrk and malloc in cAbout sbrk() and malloc()How does sbrk() work?splitting an sbrk into 2Why does calling sbrk(0) twice give a different value?

Does the problem of P vs NP come under the category of Operational Research?

Why would one number theorems, propositions and lemmas separately?

Why are sugars in whole fruits not digested the same way sugars in juice are?

Where can Batch Normalization be used? CNNs or everywhere?

Assign Error bars for y-intercept

Feedback diagram

Plotting Chebyshev polynomials using PolarPlot and FilledCurve

A conjectural trigonometric identity

Protect a 6 inch air hose from physical damage

Could flaps be raised upward to serve as spoilers / lift dumpers?

How long should I wait to plug in my refrigerator after unplugging it?

Accurately recalling the key - can everyone do it?

Adjective for when skills are not improving and I'm depressed about it

Define tcolorbox in math mode

How to draw twisted cuves?

Does KNN have a loss function?

Why are prop blades not shaped like household fan blades?

Applying for mortgage when living together but only one will be on the mortgage

Python π = 1 + (1/2) + (1/3) + (1/4) - (1/5) + (1/6) + (1/7) + (1/8) + (1/9) - (1/10) ...1748 Euler

Is there a general term for the items in a directory?

Using Python in a Bash Script

Flat maps and Zariski tangent spaces

Why does the U.S (and other Republics) not have separate capital cities for each branch of government?

Being told my "network" isn't PCI Complaint. I don't even have a server! Do I have to comply?



What's unsafe/legacy about brk/sbrk?


What does the brk() system call do?How are sbrk/brk implemented in Linux?What do brk and sbrk stand for?What does the brk() system call do?using brk to get brk_startSbrk and negative parametersbrk and malloc in cAbout sbrk() and malloc()How does sbrk() work?splitting an sbrk into 2Why does calling sbrk(0) twice give a different value?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








6















I've heard in a lot of places (musl mailing list, macOS forums, etc.) that brk() and sbrk() are unsafe. Many of these places either don't give explanations at all, or give very vague explanations. For example, this link states that "these functions are fundamentally broken", and goes on to say that the malloc and sbrk subsystems are utterly broken, that they ruin the heap, et al.



My question is: Why is this so? If malloc is used in such a way that it allocates a block of memory with sbrk large enough to quell or substantially decrease the need for further allocations, then shouldn't sbrk and brk be perfectly safe to use?



Here are my implementations of sbrk and brk:



sbrk:



#include <unistd.h>
#include <stddef.h>

void *sbrk(intptr_t inc)

intptr_t curbrk = syscall(SYS_brk, NULL);

if( inc == 0 ) goto ret;

if( curbrk < 0 ) return (void *)-1;

curbrk((void *)(curbrk+inc));
ret:
return (void *)curbrk;



brk:



#include <unistd.h>

intptr_t brk(void *ptr)

if( (void *)syscall(SYS_brk, ptr) != ptr )
return -1;
else
return 0;










share|improve this question





















  • 1





    There is explenation right there in the text For an application to use them correctly, it must depend on the malloc subsystem never being used, but this is impossible to guarantee since malloc may be used internally by libc functions without documenting this to the application.. If your app calls sbrk and your app calls malloc and malloc calls sbrk and sbrk function uses global context, the result will be a mess. They want to eliminate the sbrk function, to make users not use it, not because it is a bad design per se.

    – Kamil Cuk
    Mar 27 at 0:01












  • What does "global context" mean? A quick Google search doesn't reveal anything.

    – JL2210
    Mar 27 at 1:07











  • sbrk usually operates on a single global variable, ex __curbrk in glibc or static char *heap_end; in newlib. That means that all "contexts" (threads, functions, malloc, printf and user app) share the same ("global" to the process) data segment.

    – Kamil Cuk
    Mar 27 at 6:48






  • 2





    My guess is that certain malloc implementations are written to assume that nobody else is calling sbrk behind their back. For instance, suppose you call p = malloc(N) where N is some large number (maybe a multiple of page size). malloc does sbrk(N) to get memory from the OS and returns this pointer to you. Later (without any intervening calls to malloc) you do free(p). Now malloc "knows" that it can do sbrk(-N) to return the memory to the OS. If you have called sbrk in between, then you have a problem.

    – Nate Eldredge
    Mar 27 at 13:53






  • 1





    awkwardly written, but good basic malloc introduction for writing your own memory manager with brk/sbrk (intro level only)

    – David C. Rankin
    Mar 27 at 15:11


















6















I've heard in a lot of places (musl mailing list, macOS forums, etc.) that brk() and sbrk() are unsafe. Many of these places either don't give explanations at all, or give very vague explanations. For example, this link states that "these functions are fundamentally broken", and goes on to say that the malloc and sbrk subsystems are utterly broken, that they ruin the heap, et al.



My question is: Why is this so? If malloc is used in such a way that it allocates a block of memory with sbrk large enough to quell or substantially decrease the need for further allocations, then shouldn't sbrk and brk be perfectly safe to use?



Here are my implementations of sbrk and brk:



sbrk:



#include <unistd.h>
#include <stddef.h>

void *sbrk(intptr_t inc)

intptr_t curbrk = syscall(SYS_brk, NULL);

if( inc == 0 ) goto ret;

if( curbrk < 0 ) return (void *)-1;

curbrk((void *)(curbrk+inc));
ret:
return (void *)curbrk;



brk:



#include <unistd.h>

intptr_t brk(void *ptr)

if( (void *)syscall(SYS_brk, ptr) != ptr )
return -1;
else
return 0;










share|improve this question





















  • 1





    There is explenation right there in the text For an application to use them correctly, it must depend on the malloc subsystem never being used, but this is impossible to guarantee since malloc may be used internally by libc functions without documenting this to the application.. If your app calls sbrk and your app calls malloc and malloc calls sbrk and sbrk function uses global context, the result will be a mess. They want to eliminate the sbrk function, to make users not use it, not because it is a bad design per se.

    – Kamil Cuk
    Mar 27 at 0:01












  • What does "global context" mean? A quick Google search doesn't reveal anything.

    – JL2210
    Mar 27 at 1:07











  • sbrk usually operates on a single global variable, ex __curbrk in glibc or static char *heap_end; in newlib. That means that all "contexts" (threads, functions, malloc, printf and user app) share the same ("global" to the process) data segment.

    – Kamil Cuk
    Mar 27 at 6:48






  • 2





    My guess is that certain malloc implementations are written to assume that nobody else is calling sbrk behind their back. For instance, suppose you call p = malloc(N) where N is some large number (maybe a multiple of page size). malloc does sbrk(N) to get memory from the OS and returns this pointer to you. Later (without any intervening calls to malloc) you do free(p). Now malloc "knows" that it can do sbrk(-N) to return the memory to the OS. If you have called sbrk in between, then you have a problem.

    – Nate Eldredge
    Mar 27 at 13:53






  • 1





    awkwardly written, but good basic malloc introduction for writing your own memory manager with brk/sbrk (intro level only)

    – David C. Rankin
    Mar 27 at 15:11














6












6








6








I've heard in a lot of places (musl mailing list, macOS forums, etc.) that brk() and sbrk() are unsafe. Many of these places either don't give explanations at all, or give very vague explanations. For example, this link states that "these functions are fundamentally broken", and goes on to say that the malloc and sbrk subsystems are utterly broken, that they ruin the heap, et al.



My question is: Why is this so? If malloc is used in such a way that it allocates a block of memory with sbrk large enough to quell or substantially decrease the need for further allocations, then shouldn't sbrk and brk be perfectly safe to use?



Here are my implementations of sbrk and brk:



sbrk:



#include <unistd.h>
#include <stddef.h>

void *sbrk(intptr_t inc)

intptr_t curbrk = syscall(SYS_brk, NULL);

if( inc == 0 ) goto ret;

if( curbrk < 0 ) return (void *)-1;

curbrk((void *)(curbrk+inc));
ret:
return (void *)curbrk;



brk:



#include <unistd.h>

intptr_t brk(void *ptr)

if( (void *)syscall(SYS_brk, ptr) != ptr )
return -1;
else
return 0;










share|improve this question
















I've heard in a lot of places (musl mailing list, macOS forums, etc.) that brk() and sbrk() are unsafe. Many of these places either don't give explanations at all, or give very vague explanations. For example, this link states that "these functions are fundamentally broken", and goes on to say that the malloc and sbrk subsystems are utterly broken, that they ruin the heap, et al.



My question is: Why is this so? If malloc is used in such a way that it allocates a block of memory with sbrk large enough to quell or substantially decrease the need for further allocations, then shouldn't sbrk and brk be perfectly safe to use?



Here are my implementations of sbrk and brk:



sbrk:



#include <unistd.h>
#include <stddef.h>

void *sbrk(intptr_t inc)

intptr_t curbrk = syscall(SYS_brk, NULL);

if( inc == 0 ) goto ret;

if( curbrk < 0 ) return (void *)-1;

curbrk((void *)(curbrk+inc));
ret:
return (void *)curbrk;



brk:



#include <unistd.h>

intptr_t brk(void *ptr)

if( (void *)syscall(SYS_brk, ptr) != ptr )
return -1;
else
return 0;







c malloc legacy sbrk brk






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 27 at 12:42







JL2210

















asked Mar 26 at 23:50









JL2210JL2210

2,3041 gold badge8 silver badges34 bronze badges




2,3041 gold badge8 silver badges34 bronze badges










  • 1





    There is explenation right there in the text For an application to use them correctly, it must depend on the malloc subsystem never being used, but this is impossible to guarantee since malloc may be used internally by libc functions without documenting this to the application.. If your app calls sbrk and your app calls malloc and malloc calls sbrk and sbrk function uses global context, the result will be a mess. They want to eliminate the sbrk function, to make users not use it, not because it is a bad design per se.

    – Kamil Cuk
    Mar 27 at 0:01












  • What does "global context" mean? A quick Google search doesn't reveal anything.

    – JL2210
    Mar 27 at 1:07











  • sbrk usually operates on a single global variable, ex __curbrk in glibc or static char *heap_end; in newlib. That means that all "contexts" (threads, functions, malloc, printf and user app) share the same ("global" to the process) data segment.

    – Kamil Cuk
    Mar 27 at 6:48






  • 2





    My guess is that certain malloc implementations are written to assume that nobody else is calling sbrk behind their back. For instance, suppose you call p = malloc(N) where N is some large number (maybe a multiple of page size). malloc does sbrk(N) to get memory from the OS and returns this pointer to you. Later (without any intervening calls to malloc) you do free(p). Now malloc "knows" that it can do sbrk(-N) to return the memory to the OS. If you have called sbrk in between, then you have a problem.

    – Nate Eldredge
    Mar 27 at 13:53






  • 1





    awkwardly written, but good basic malloc introduction for writing your own memory manager with brk/sbrk (intro level only)

    – David C. Rankin
    Mar 27 at 15:11













  • 1





    There is explenation right there in the text For an application to use them correctly, it must depend on the malloc subsystem never being used, but this is impossible to guarantee since malloc may be used internally by libc functions without documenting this to the application.. If your app calls sbrk and your app calls malloc and malloc calls sbrk and sbrk function uses global context, the result will be a mess. They want to eliminate the sbrk function, to make users not use it, not because it is a bad design per se.

    – Kamil Cuk
    Mar 27 at 0:01












  • What does "global context" mean? A quick Google search doesn't reveal anything.

    – JL2210
    Mar 27 at 1:07











  • sbrk usually operates on a single global variable, ex __curbrk in glibc or static char *heap_end; in newlib. That means that all "contexts" (threads, functions, malloc, printf and user app) share the same ("global" to the process) data segment.

    – Kamil Cuk
    Mar 27 at 6:48






  • 2





    My guess is that certain malloc implementations are written to assume that nobody else is calling sbrk behind their back. For instance, suppose you call p = malloc(N) where N is some large number (maybe a multiple of page size). malloc does sbrk(N) to get memory from the OS and returns this pointer to you. Later (without any intervening calls to malloc) you do free(p). Now malloc "knows" that it can do sbrk(-N) to return the memory to the OS. If you have called sbrk in between, then you have a problem.

    – Nate Eldredge
    Mar 27 at 13:53






  • 1





    awkwardly written, but good basic malloc introduction for writing your own memory manager with brk/sbrk (intro level only)

    – David C. Rankin
    Mar 27 at 15:11








1




1





There is explenation right there in the text For an application to use them correctly, it must depend on the malloc subsystem never being used, but this is impossible to guarantee since malloc may be used internally by libc functions without documenting this to the application.. If your app calls sbrk and your app calls malloc and malloc calls sbrk and sbrk function uses global context, the result will be a mess. They want to eliminate the sbrk function, to make users not use it, not because it is a bad design per se.

– Kamil Cuk
Mar 27 at 0:01






There is explenation right there in the text For an application to use them correctly, it must depend on the malloc subsystem never being used, but this is impossible to guarantee since malloc may be used internally by libc functions without documenting this to the application.. If your app calls sbrk and your app calls malloc and malloc calls sbrk and sbrk function uses global context, the result will be a mess. They want to eliminate the sbrk function, to make users not use it, not because it is a bad design per se.

– Kamil Cuk
Mar 27 at 0:01














What does "global context" mean? A quick Google search doesn't reveal anything.

– JL2210
Mar 27 at 1:07





What does "global context" mean? A quick Google search doesn't reveal anything.

– JL2210
Mar 27 at 1:07













sbrk usually operates on a single global variable, ex __curbrk in glibc or static char *heap_end; in newlib. That means that all "contexts" (threads, functions, malloc, printf and user app) share the same ("global" to the process) data segment.

– Kamil Cuk
Mar 27 at 6:48





sbrk usually operates on a single global variable, ex __curbrk in glibc or static char *heap_end; in newlib. That means that all "contexts" (threads, functions, malloc, printf and user app) share the same ("global" to the process) data segment.

– Kamil Cuk
Mar 27 at 6:48




2




2





My guess is that certain malloc implementations are written to assume that nobody else is calling sbrk behind their back. For instance, suppose you call p = malloc(N) where N is some large number (maybe a multiple of page size). malloc does sbrk(N) to get memory from the OS and returns this pointer to you. Later (without any intervening calls to malloc) you do free(p). Now malloc "knows" that it can do sbrk(-N) to return the memory to the OS. If you have called sbrk in between, then you have a problem.

– Nate Eldredge
Mar 27 at 13:53





My guess is that certain malloc implementations are written to assume that nobody else is calling sbrk behind their back. For instance, suppose you call p = malloc(N) where N is some large number (maybe a multiple of page size). malloc does sbrk(N) to get memory from the OS and returns this pointer to you. Later (without any intervening calls to malloc) you do free(p). Now malloc "knows" that it can do sbrk(-N) to return the memory to the OS. If you have called sbrk in between, then you have a problem.

– Nate Eldredge
Mar 27 at 13:53




1




1





awkwardly written, but good basic malloc introduction for writing your own memory manager with brk/sbrk (intro level only)

– David C. Rankin
Mar 27 at 15:11






awkwardly written, but good basic malloc introduction for writing your own memory manager with brk/sbrk (intro level only)

– David C. Rankin
Mar 27 at 15:11













1 Answer
1






active

oldest

votes


















3














The reality highly depends on the implementation but here are some elements:



unsafe



brk/sbrk were invented to allow a process to request more memory from the system, and release it in a single contiguous segment. As such, they were used by many malloc and free implementations. The problem was that, as it returned a unique segment, things would go wrong as multiple modules (of the same process) use it directly. It became even worse in a multi-threaded process because of race conditions. Suppose 2 threads want to add new memory. They will look at the current top address with sbrk(0), see the same address, request new memory with either brk or sbrk, and because of the race condition, will both use the same memory.



Even in a single threaded process, some malloc and free implementations assume that they only are allowed to use the low level s/brk interface, and that any other code should use them. In that case things will go wrong if the image of the break segment that they internally maintain is no longer the assumed value. They should have to guess that some parts of the segment are "reserved" for other uses, possibly breaking the ability to release any memory.



For that reason, user code should never directly use brk/sbrk and only rely on malloc/free. If, and only if, you are writing an implementation of the standard library including malloc/realloc/calloc/free, you can safely use brk/sbrk



legacy



On modern system, mmap can make a much nicer usage of virtual memory management. You can use as many dynamic memory segments as you need with no interaction between them. So, on a modern system, unless you have a specific need for memory allocation using brk/sbrk, you should use mmap.



portability



The FreeBSD reference for brk and sbrk states this:




The brk() and sbrk() functions are legacy interfaces from before the
advent of modern virtual memory management.




and later:




BUGS:
Mixing brk() or sbrk() with malloc(3), free(3), or similar functions will
result in non-portable program behavior.







share|improve this answer



























  • That's about as good an explanation I've seen. Don't mix malloc with your owns calls to brk/sbrk. I think you are right. If malloc can't find the break where it left it, then it likely won't release any of the memory it originally allocated. I haven't looked at the malloc source, but that makes sense.

    – David C. Rankin
    Mar 27 at 15:17











  • This is definitely a better explanation than I've seen so far. However, it begs the question: If I can make malloc() and free() check for program break changes, is it possible to safely use sbrk() and brk() with my C library? I'll also give you a +1 for mentioning threads. I haven't implemented them yet, so I hadn't thought about it. Thanks!

    – JL2210
    Mar 27 at 15:40











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55367809%2fwhats-unsafe-legacy-about-brk-sbrk%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









3














The reality highly depends on the implementation but here are some elements:



unsafe



brk/sbrk were invented to allow a process to request more memory from the system, and release it in a single contiguous segment. As such, they were used by many malloc and free implementations. The problem was that, as it returned a unique segment, things would go wrong as multiple modules (of the same process) use it directly. It became even worse in a multi-threaded process because of race conditions. Suppose 2 threads want to add new memory. They will look at the current top address with sbrk(0), see the same address, request new memory with either brk or sbrk, and because of the race condition, will both use the same memory.



Even in a single threaded process, some malloc and free implementations assume that they only are allowed to use the low level s/brk interface, and that any other code should use them. In that case things will go wrong if the image of the break segment that they internally maintain is no longer the assumed value. They should have to guess that some parts of the segment are "reserved" for other uses, possibly breaking the ability to release any memory.



For that reason, user code should never directly use brk/sbrk and only rely on malloc/free. If, and only if, you are writing an implementation of the standard library including malloc/realloc/calloc/free, you can safely use brk/sbrk



legacy



On modern system, mmap can make a much nicer usage of virtual memory management. You can use as many dynamic memory segments as you need with no interaction between them. So, on a modern system, unless you have a specific need for memory allocation using brk/sbrk, you should use mmap.



portability



The FreeBSD reference for brk and sbrk states this:




The brk() and sbrk() functions are legacy interfaces from before the
advent of modern virtual memory management.




and later:




BUGS:
Mixing brk() or sbrk() with malloc(3), free(3), or similar functions will
result in non-portable program behavior.







share|improve this answer



























  • That's about as good an explanation I've seen. Don't mix malloc with your owns calls to brk/sbrk. I think you are right. If malloc can't find the break where it left it, then it likely won't release any of the memory it originally allocated. I haven't looked at the malloc source, but that makes sense.

    – David C. Rankin
    Mar 27 at 15:17











  • This is definitely a better explanation than I've seen so far. However, it begs the question: If I can make malloc() and free() check for program break changes, is it possible to safely use sbrk() and brk() with my C library? I'll also give you a +1 for mentioning threads. I haven't implemented them yet, so I hadn't thought about it. Thanks!

    – JL2210
    Mar 27 at 15:40
















3














The reality highly depends on the implementation but here are some elements:



unsafe



brk/sbrk were invented to allow a process to request more memory from the system, and release it in a single contiguous segment. As such, they were used by many malloc and free implementations. The problem was that, as it returned a unique segment, things would go wrong as multiple modules (of the same process) use it directly. It became even worse in a multi-threaded process because of race conditions. Suppose 2 threads want to add new memory. They will look at the current top address with sbrk(0), see the same address, request new memory with either brk or sbrk, and because of the race condition, will both use the same memory.



Even in a single threaded process, some malloc and free implementations assume that they only are allowed to use the low level s/brk interface, and that any other code should use them. In that case things will go wrong if the image of the break segment that they internally maintain is no longer the assumed value. They should have to guess that some parts of the segment are "reserved" for other uses, possibly breaking the ability to release any memory.



For that reason, user code should never directly use brk/sbrk and only rely on malloc/free. If, and only if, you are writing an implementation of the standard library including malloc/realloc/calloc/free, you can safely use brk/sbrk



legacy



On modern system, mmap can make a much nicer usage of virtual memory management. You can use as many dynamic memory segments as you need with no interaction between them. So, on a modern system, unless you have a specific need for memory allocation using brk/sbrk, you should use mmap.



portability



The FreeBSD reference for brk and sbrk states this:




The brk() and sbrk() functions are legacy interfaces from before the
advent of modern virtual memory management.




and later:




BUGS:
Mixing brk() or sbrk() with malloc(3), free(3), or similar functions will
result in non-portable program behavior.







share|improve this answer



























  • That's about as good an explanation I've seen. Don't mix malloc with your owns calls to brk/sbrk. I think you are right. If malloc can't find the break where it left it, then it likely won't release any of the memory it originally allocated. I haven't looked at the malloc source, but that makes sense.

    – David C. Rankin
    Mar 27 at 15:17











  • This is definitely a better explanation than I've seen so far. However, it begs the question: If I can make malloc() and free() check for program break changes, is it possible to safely use sbrk() and brk() with my C library? I'll also give you a +1 for mentioning threads. I haven't implemented them yet, so I hadn't thought about it. Thanks!

    – JL2210
    Mar 27 at 15:40














3












3








3







The reality highly depends on the implementation but here are some elements:



unsafe



brk/sbrk were invented to allow a process to request more memory from the system, and release it in a single contiguous segment. As such, they were used by many malloc and free implementations. The problem was that, as it returned a unique segment, things would go wrong as multiple modules (of the same process) use it directly. It became even worse in a multi-threaded process because of race conditions. Suppose 2 threads want to add new memory. They will look at the current top address with sbrk(0), see the same address, request new memory with either brk or sbrk, and because of the race condition, will both use the same memory.



Even in a single threaded process, some malloc and free implementations assume that they only are allowed to use the low level s/brk interface, and that any other code should use them. In that case things will go wrong if the image of the break segment that they internally maintain is no longer the assumed value. They should have to guess that some parts of the segment are "reserved" for other uses, possibly breaking the ability to release any memory.



For that reason, user code should never directly use brk/sbrk and only rely on malloc/free. If, and only if, you are writing an implementation of the standard library including malloc/realloc/calloc/free, you can safely use brk/sbrk



legacy



On modern system, mmap can make a much nicer usage of virtual memory management. You can use as many dynamic memory segments as you need with no interaction between them. So, on a modern system, unless you have a specific need for memory allocation using brk/sbrk, you should use mmap.



portability



The FreeBSD reference for brk and sbrk states this:




The brk() and sbrk() functions are legacy interfaces from before the
advent of modern virtual memory management.




and later:




BUGS:
Mixing brk() or sbrk() with malloc(3), free(3), or similar functions will
result in non-portable program behavior.







share|improve this answer















The reality highly depends on the implementation but here are some elements:



unsafe



brk/sbrk were invented to allow a process to request more memory from the system, and release it in a single contiguous segment. As such, they were used by many malloc and free implementations. The problem was that, as it returned a unique segment, things would go wrong as multiple modules (of the same process) use it directly. It became even worse in a multi-threaded process because of race conditions. Suppose 2 threads want to add new memory. They will look at the current top address with sbrk(0), see the same address, request new memory with either brk or sbrk, and because of the race condition, will both use the same memory.



Even in a single threaded process, some malloc and free implementations assume that they only are allowed to use the low level s/brk interface, and that any other code should use them. In that case things will go wrong if the image of the break segment that they internally maintain is no longer the assumed value. They should have to guess that some parts of the segment are "reserved" for other uses, possibly breaking the ability to release any memory.



For that reason, user code should never directly use brk/sbrk and only rely on malloc/free. If, and only if, you are writing an implementation of the standard library including malloc/realloc/calloc/free, you can safely use brk/sbrk



legacy



On modern system, mmap can make a much nicer usage of virtual memory management. You can use as many dynamic memory segments as you need with no interaction between them. So, on a modern system, unless you have a specific need for memory allocation using brk/sbrk, you should use mmap.



portability



The FreeBSD reference for brk and sbrk states this:




The brk() and sbrk() functions are legacy interfaces from before the
advent of modern virtual memory management.




and later:




BUGS:
Mixing brk() or sbrk() with malloc(3), free(3), or similar functions will
result in non-portable program behavior.








share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 27 at 16:30









JL2210

2,3041 gold badge8 silver badges34 bronze badges




2,3041 gold badge8 silver badges34 bronze badges










answered Mar 27 at 15:05









Serge BallestaSerge Ballesta

88.8k9 gold badges68 silver badges146 bronze badges




88.8k9 gold badges68 silver badges146 bronze badges















  • That's about as good an explanation I've seen. Don't mix malloc with your owns calls to brk/sbrk. I think you are right. If malloc can't find the break where it left it, then it likely won't release any of the memory it originally allocated. I haven't looked at the malloc source, but that makes sense.

    – David C. Rankin
    Mar 27 at 15:17











  • This is definitely a better explanation than I've seen so far. However, it begs the question: If I can make malloc() and free() check for program break changes, is it possible to safely use sbrk() and brk() with my C library? I'll also give you a +1 for mentioning threads. I haven't implemented them yet, so I hadn't thought about it. Thanks!

    – JL2210
    Mar 27 at 15:40


















  • That's about as good an explanation I've seen. Don't mix malloc with your owns calls to brk/sbrk. I think you are right. If malloc can't find the break where it left it, then it likely won't release any of the memory it originally allocated. I haven't looked at the malloc source, but that makes sense.

    – David C. Rankin
    Mar 27 at 15:17











  • This is definitely a better explanation than I've seen so far. However, it begs the question: If I can make malloc() and free() check for program break changes, is it possible to safely use sbrk() and brk() with my C library? I'll also give you a +1 for mentioning threads. I haven't implemented them yet, so I hadn't thought about it. Thanks!

    – JL2210
    Mar 27 at 15:40

















That's about as good an explanation I've seen. Don't mix malloc with your owns calls to brk/sbrk. I think you are right. If malloc can't find the break where it left it, then it likely won't release any of the memory it originally allocated. I haven't looked at the malloc source, but that makes sense.

– David C. Rankin
Mar 27 at 15:17





That's about as good an explanation I've seen. Don't mix malloc with your owns calls to brk/sbrk. I think you are right. If malloc can't find the break where it left it, then it likely won't release any of the memory it originally allocated. I haven't looked at the malloc source, but that makes sense.

– David C. Rankin
Mar 27 at 15:17













This is definitely a better explanation than I've seen so far. However, it begs the question: If I can make malloc() and free() check for program break changes, is it possible to safely use sbrk() and brk() with my C library? I'll also give you a +1 for mentioning threads. I haven't implemented them yet, so I hadn't thought about it. Thanks!

– JL2210
Mar 27 at 15:40






This is definitely a better explanation than I've seen so far. However, it begs the question: If I can make malloc() and free() check for program break changes, is it possible to safely use sbrk() and brk() with my C library? I'll also give you a +1 for mentioning threads. I haven't implemented them yet, so I hadn't thought about it. Thanks!

– JL2210
Mar 27 at 15:40









Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.







Got a question that you can’t ask on public Stack Overflow? Learn more about sharing private information with Stack Overflow for Teams.



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55367809%2fwhats-unsafe-legacy-about-brk-sbrk%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

용인 삼성생명 블루밍스 목차 통계 역대 감독 선수단 응원단 경기장 같이 보기 외부 링크 둘러보기 메뉴samsungblueminx.comeh선수 명단용인 삼성생명 블루밍스용인 삼성생명 블루밍스ehsamsungblueminx.comeheheheh

155 수학 과학 기타 둘러보기 메뉴eh추가해eh문서를 완성해