/* Set the new data segment end to NEWBRK. If this succeeds, return
NEWBRK, else return the current data segment end. */
-static Addr do_brk ( Addr newbrk )
+static Addr do_brk ( Addr newbrk, ThreadId tid )
{
NSegment const* aseg;
Addr newbrkP;
vg_assert(delta > 0);
vg_assert(VG_IS_PAGE_ALIGNED(delta));
- Bool overflow; // ignored here
+ Bool overflow;
if (! VG_(am_extend_into_adjacent_reservation_client)( aseg->start, delta,
- &overflow))
+ &overflow)) {
+ if (overflow)
+ VG_(umsg)("brk segment overflow in thread #%d: can't grow to %#lx\n",
+ tid, newbrkP);
+ else
+ VG_(umsg)("Cannot map memory to grow brk segment in thread #%d "
+ "to %#lx\n", tid, newbrkP);
goto bad;
+ }
VG_(brk_limit) = newbrk;
return newbrk;
PRINT("sys_brk ( %#lx )", ARG1);
PRE_REG_READ1(unsigned long, "brk", unsigned long, end_data_segment);
- brk_new = do_brk(ARG1);
+ brk_new = do_brk(ARG1, tid);
SET_STATUS_Success( brk_new );
if (brk_new == ARG1) {
EXTRA_DIST = \
blockfault.stderr.exp blockfault.vgtest \
+ brk-overflow1.stderr.exp brk-overflow1.vgtest \
+ brk-overflow2.stderr.exp brk-overflow2.vgtest \
mremap.stderr.exp mremap.stderr.exp-glibc27 mremap.stdout.exp \
mremap.vgtest \
mremap2.stderr.exp mremap2.stdout.exp mremap2.vgtest \
check_PROGRAMS = \
blockfault \
+ brk-overflow1 \
+ brk-overflow2 \
mremap \
mremap2 \
mremap3 \
--- /dev/null
+#include <unistd.h>
+
+volatile void *ptr;
+
+/* The default size of the brk segment is 8 MB.
+ Request more than that in a single request. */
+int main()
+{
+ ptr = sbrk(9*1024*1024);
+
+ return 0;
+}
--- /dev/null
+#include <unistd.h>
+
+volatile void *ptr;
+
+/* The default size of the brk segment is 8 MB.
+ Request more than that in a sequence of requests */
+int main()
+{
+ int i;
+ for (i=0; i < 10; ++i) {
+ ptr = sbrk(1024*1024);
+ }
+ return 0;
+}
--- /dev/null
+
+brk segment overflow in thread #1: can't grow to 0x........
+brk segment overflow in thread #1: can't grow to 0x........
+brk segment overflow in thread #1: can't grow to 0x........
+