Fix problem with brk(). Thanks to Paull Mackerras for the patch.
Added a regression test for it.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2619 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/vg_syscalls.c b/coregrind/vg_syscalls.c
index 0d87da8..c279aae 100644
--- a/coregrind/vg_syscalls.c
+++ b/coregrind/vg_syscalls.c
@@ -900,6 +900,8 @@
Addr ret = VG_(brk_limit);
static const Bool debug = False;
Segment *seg;
+ Addr current, newaddr;
+
if (debug)
VG_(printf)("do_brk: brk_base=%p brk_limit=%p newbrk=%p\n",
@@ -922,9 +924,9 @@
if (seg != NULL && newbrk > seg->addr)
return VG_(brk_limit);
- if (PGROUNDDN(newbrk) != PGROUNDDN(VG_(brk_limit))) {
- Addr current = PGROUNDUP(VG_(brk_limit));
- Addr newaddr = PGROUNDUP(newbrk);
+ current = PGROUNDUP(VG_(brk_limit));
+ newaddr = PGROUNDUP(newbrk);
+ if (newaddr != current) {
/* new brk in a new page - fix the mappings */
if (newbrk > VG_(brk_limit)) {
diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am
index 4d3035e..a8fccb8 100644
--- a/memcheck/tests/Makefile.am
+++ b/memcheck/tests/Makefile.am
@@ -18,6 +18,7 @@
badloop.stderr.exp badloop.vgtest \
badrw.stderr.exp badrw.vgtest \
brk.stderr.exp brk.vgtest \
+ brk2.stderr.exp brk2.vgtest \
buflen_check.stderr.exp buflen_check.vgtest \
clientperm.stderr.exp \
clientperm.stdout.exp clientperm.vgtest \
@@ -77,7 +78,7 @@
zeropage.stderr.exp zeropage.vgtest
check_PROGRAMS = \
- badaddrvalue badfree badjump badloop badrw brk buflen_check \
+ badaddrvalue badfree badjump badloop badrw brk brk2 buflen_check \
clientperm custom_alloc \
doublefree error_counts errs1 exitprog execve execve2 \
fpeflags fprw fwrite inits inline \
@@ -100,6 +101,7 @@
badloop_SOURCES = badloop.c
badrw_SOURCES = badrw.c
brk_SOURCES = brk.c
+brk2_SOURCES = brk2.c
buflen_check_SOURCES = buflen_check.c
clientperm_SOURCES = clientperm.c
custom_alloc_SOURCES = custom_alloc.c
diff --git a/memcheck/tests/brk2.c b/memcheck/tests/brk2.c
new file mode 100644
index 0000000..3a88133
--- /dev/null
+++ b/memcheck/tests/brk2.c
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <unistd.h>
+
+#define MAX 3000
+
+// At one time, this was causing a seg fault within Valgrind -- it was when
+// extending the brk segment onto a new page. Fixed in vg_syscalls.c 1.129.
+
+int main () {
+ char* ptr;
+ int i;
+
+ for (i=0; i<MAX; i++) {
+ ptr = sbrk(1);
+
+ if (ptr == (void*)-1) {
+ printf ("sbrk() failed!\n");
+ return 0;
+ }
+
+ *ptr = 0;
+ }
+
+ return 0;
+}
diff --git a/memcheck/tests/brk2.stderr.exp b/memcheck/tests/brk2.stderr.exp
new file mode 100644
index 0000000..c4aa6f0
--- /dev/null
+++ b/memcheck/tests/brk2.stderr.exp
@@ -0,0 +1,7 @@
+
+
+ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
+malloc/free: in use at exit: 0 bytes in 0 blocks.
+malloc/free: 0 allocs, 0 frees, 0 bytes allocated.
+For a detailed leak analysis, rerun with: --leak-check=yes
+For counts of detected errors, rerun with: -v
diff --git a/memcheck/tests/brk2.vgtest b/memcheck/tests/brk2.vgtest
new file mode 100644
index 0000000..951b3fa
--- /dev/null
+++ b/memcheck/tests/brk2.vgtest
@@ -0,0 +1 @@
+prog: brk2