Bug 19319 - Mudflap produce many violations on simple, correct c++ program
Summary: Mudflap produce many violations on simple, correct c++ program
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libmudflap (show other bugs)
Version: 4.0.0
: P2 normal
Target Milestone: ---
Assignee: Frank Ch. Eigler
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-01-07 22:31 UTC by bredelin
Modified: 2014-02-16 09:59 UTC (History)
10 users (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2006-03-19 05:11:47


Attachments
test case mentioned in Comment #19 (203 bytes, text/plain)
2006-11-10 16:35 UTC, p.van-hoof
Details
annotated transcript (3.88 KB, text/plain)
2006-11-14 04:26 UTC, Paul Pluzhnikov
Details
Patch for tree-mudflap.c (1.03 KB, patch)
2007-06-10 19:35 UTC, Alex Lamaison
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description bredelin 2005-01-07 22:31:37 UTC
The following extremely short program generates several 'violations':

#include <vector>

int main() {
  std::vector<int> v;
  v.push_back(1);
} 

Here are the violations:
*******
mudflap violation 1 (check/write): time=1105134174.644364 ptr=0xbffff820 size=4
pc=0x4001f6b8
location=`/usr/local/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../include/c++/4.0.0/bits/stl_iterator.h:603
(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> >
>::__normal_iterator)'
      /usr/local/lib/libmudflap.so.0(__mf_check+0x48) [0x4001f6b8]
     
./test4(_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEC1ERKS1_+0xf6)
[0x804b728]
      ./test4(_ZNSt6vectorIiSaIiEE3endEv+0x1c) [0x804b74e]
Nearby object 1: checked region begins 16B before and ends 13B before
mudflap object 0x80d5508:
name=`/usr/local/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../include/c++/4.0.0/bits/stl_vector.h:610
(std::vector<int, std::allocator<int> >::push_back) <unnamed variable>'
bounds=[0xbffff830,0xbffff833] size=4 area=stack check=0r/0w liveness=0
alloc time=1105134174.644358 pc=0x400201a8
number of nearby objects: 1
*******
mudflap violation 2 (check/write): time=1105134174.644572 ptr=0xbffff640 size=4
pc=0x4001f6b8
location=`/usr/local/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../include/c++/4.0.0/bits/stl_iterator.h:603
(__gnu_cxx::__normal_iterator<const int*, std::vector<int, std::allocator<int> >
>::__normal_iterator)'
      /usr/local/lib/libmudflap.so.0(__mf_check+0x48) [0x4001f6b8]
     
./test4(_ZN9__gnu_cxx17__normal_iteratorIPKiSt6vectorIiSaIiEEEC1ERKS2_+0xf6)
[0x804c31c]
      ./test4(_ZNKSt6vectorIiSaIiEE5beginEv+0xb0) [0x804c3d6]
Nearby object 1: checked region begins 12B before and ends 9B before
mudflap object 0x80d5bf0:
name=`/usr/local/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../include/c++/4.0.0/bits/stl_vector.h:403
(std::vector<int, std::allocator<int> >::size) <unnamed variable>'
bounds=[0xbffff64c,0xbffff64f] size=4 area=stack check=0r/0w liveness=0
alloc time=1105134174.644566 pc=0x400201a8
Nearby object 2: checked region begins 16B before and ends 13B before
mudflap object 0x80d5c58:
name=`/usr/local/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../include/c++/4.0.0/bits/stl_vector.h:403
(std::vector<int, std::allocator<int> >::size) <unnamed variable>'
bounds=[0xbffff650,0xbffff653] size=4 area=stack check=0r/0w liveness=0
alloc time=1105134174.644567 pc=0x400201a8
number of nearby objects: 2
 ...etc...
*******
mudflap violation 6 (check/write): time=1105134174.645166 ptr=0xbffff760 size=4
pc=0x4001f6b8
location=`/usr/local/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../include/c++/4.0.0/bits/stl_iterator.h:603
(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> >
>::__normal_iterator)'
      /usr/local/lib/libmudflap.so.0(__mf_check+0x48) [0x4001f6b8]
     
./test4(_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEC1ERKS1_+0xf6)
[0x804b728]
      ./test4(_ZNSt6vectorIiSaIiEE3endEv+0x1c) [0x804b74e]
Nearby object 1: checked region begins 28B before and ends 25B before
mudflap object 0x80d5b88:
name=`/usr/local/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../include/c++/4.0.0/bits/vector.tcc:276
(std::vector<int, std::allocator<int> >::_M_insert_aux)
__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >
__new_finish'
bounds=[0xbffff77c,0xbffff77f] size=4 area=stack check=1r/0w liveness=1
alloc time=1105134174.644565 pc=0x400201a8
Nearby object 2: checked region begins 32B before and ends 29B before
mudflap object 0x80d5b20:
name=`/usr/local/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../include/c++/4.0.0/bits/vector.tcc:275
(std::vector<int, std::allocator<int> >::_M_insert_aux)
__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >
__new_start'
bounds=[0xbffff780,0xbffff783] size=4 area=stack check=0r/1w liveness=1
alloc time=1105134174.644564 pc=0x400201a8
Nearby object 3: checked region begins 36B before and ends 33B before
mudflap object 0x80d5570:
name=`/usr/local/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../include/c++/4.0.0/bits/vector.tcc:257
(std::vector<int, std::allocator<int> >::_M_insert_aux) <unnamed variable>'
bounds=[0xbffff784,0xbffff787] size=4 area=stack check=0r/0w liveness=0
alloc time=1105134174.644549 pc=0x400201a8
Nearby object 9: checked region begins 241B after and ends 244B after
mudflap dead object 0x80d66e0:
name=`/usr/local/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../include/c++/4.0.0/bits/stl_uninitialized.h:252
(__uninitialized_copy_a<__gnu_cxx::__normal_iterator<int*, std::vector<int,
std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int,
std::allocator<int> > >, int>) __gnu_cxx::__normal_iterator<int*,
std::vector<int, std::allocator<int> > > __result'
bounds=[0xbffff66c,0xbffff66f] size=4 area=stack check=0r/0w liveness=0
alloc time=1105134174.645015 pc=0x400201a8
dealloc time=1105134174.645163 pc=0x4001fcb1
number of nearby objects: 9
*******
mudflap violation 7 (check/write): time=1105134174.645279 ptr=0xbffff75c size=4
pc=0x4001f6b8
location=`/usr/local/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../include/c++/4.0.0/bits/stl_iterator.h:603
(__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> >
>::__normal_iterator)'
      /usr/local/lib/libmudflap.so.0(__mf_check+0x48) [0x4001f6b8]
     
./test4(_ZN9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEC1ERKS1_+0xf6)
[0x804b728]
      ./test4(_ZNSt6vectorIiSaIiEE5beginEv+0x19) [0x804b8ff]
Nearby object 1: checked region begins 32B before and ends 29B before
mudflap object 0x80d5b88:
name=`/usr/local/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../include/c++/4.0.0/bits/vector.tcc:276
(std::vector<int, std::allocator<int> >::_M_insert_aux)
__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >
__new_finish'
Nearby object 2: checked region begins 36B before and ends 33B before
mudflap object 0x80d5b20:
name=`/usr/local/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../include/c++/4.0.0/bits/vector.tcc:275
(std::vector<int, std::allocator<int> >::_M_insert_aux)
__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int> > >
__new_start'
Nearby object 3: checked region begins 40B before and ends 37B before
mudflap object 0x80d5570:
name=`/usr/local/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../include/c++/4.0.0/bits/vector.tcc:257
(std::vector<int, std::allocator<int> >::_M_insert_aux) <unnamed variable>'
Nearby object 8: checked region begins 237B after and ends 240B after
mudflap dead object 0x80d66e0:
name=`/usr/local/lib/gcc/i686-pc-linux-gnu/4.0.0/../../../../include/c++/4.0.0/bits/stl_uninitialized.h:252
(__uninitialized_copy_a<__gnu_cxx::__normal_iterator<int*, std::vector<int,
std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*, std::vector<int,
std::allocator<int> > >, int>) __gnu_cxx::__normal_iterator<int*,
std::vector<int, std::allocator<int> > > __result'
number of nearby objects: 8
Comment 1 Frank Ch. Eigler 2005-01-07 22:58:18 UTC
Here is a simpler test case for at least one of the problems.

struct k {
  int data;
  k(int j): data(j) {}
};
k make_k () { return k(1); }
int main ()
{
  k foo = make_k ();
  return 0;
}
Comment 2 Wolfgang Bangerth 2005-01-08 20:03:22 UTC
Analysis is here and in the follow-up: 
  http://gcc.gnu.org/ml/gcc/2005-01/msg00460.html 
Comment 3 Frank Ch. Eigler 2005-01-10 17:04:38 UTC
This patch appears to fix the problem: testing and getting approvals

--- gimplify.c  1 Jan 2005 01:43:08 -0000       2.101
+++ gimplify.c  10 Jan 2005 17:03:54 -0000
@@ -2949,6 +2949,15 @@ gimplify_modify_expr (tree *expr_p, tree
   if (ret != GS_UNHANDLED)
     return ret;
  
+  /* Handle aggregate returns from function calls.  We need to mark
+     the LHS addressable, since the expanded call will pass its
+     address as a hidden argument.  */
+  if (TREE_CODE (*from_p) == CALL_EXPR)
+    {
+      if (aggregate_value_p (*to_p, *from_p))
+        lang_hooks.mark_addressable (*to_p);
+    }
+
   /* If we've got a variable sized assignment between two lvalues (i.e. does
      not involve a call), then we can make things a bit more straightforward
      by converting the assignment to memcpy or memset.  */
Comment 4 bredelin 2005-01-18 09:35:18 UTC
Note that this is not just a bug in mudflap, but a bug in the middle end:

http://gcc.gnu.org/ml/gcc-patches/2005-01/msg00579.html

See follow-up on above message for a mention of a patch for this.
Comment 5 CVS Commits 2005-02-13 06:44:05 UTC
Subject: Bug 19319

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	jason@gcc.gnu.org	2005-02-13 06:43:58

Modified files:
	gcc            : ChangeLog fold-const.c gimplify.c tree.h 

Log message:
	PR mudflap/19319
	* gimplify.c (gimplify_modify_expr_rhs) [CALL_EXPR]: Make return
	slot explicit.
	
	PR c++/16405
	* fold-const.c (fold_indirect_ref_1): Split out from...
	(build_fold_indirect_ref): Here.
	(fold_indirect_ref): New fn.
	* tree.h: Declare it.
	* gimplify.c (gimplify_compound_lval): Call fold_indirect_ref.
	(gimplify_modify_expr_rhs): Likewise.
	(gimplify_expr): Likewise.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.7461&r2=2.7462
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/fold-const.c.diff?cvsroot=gcc&r1=1.507&r2=1.508
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/gimplify.c.diff?cvsroot=gcc&r1=2.108&r2=2.109
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree.h.diff?cvsroot=gcc&r1=1.689&r2=1.690

Comment 6 CVS Commits 2005-02-13 12:49:42 UTC
Subject: Bug 19319

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	fche@gcc.gnu.org	2005-02-13 12:49:34

Modified files:
	libmudflap     : ChangeLog 
Added files:
	libmudflap/testsuite/libmudflap.c++: pass55-frag.cxx 

Log message:
	2005-02-13  Frank Ch. Eigler  <fche@redhat.com>
	
	PR mudflap/19319
	* testsuite/libmudflap.c++/pass55-frag.c: New test.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libmudflap/ChangeLog.diff?cvsroot=gcc&r1=1.48&r2=1.49
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libmudflap/testsuite/libmudflap.c++/pass55-frag.cxx.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 7 Frank Ch. Eigler 2005-02-13 12:50:38 UTC
Thank you, Jason!
Comment 8 CVS Commits 2005-02-17 05:37:34 UTC
Subject: Bug 19319

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	jason@gcc.gnu.org	2005-02-17 05:37:21

Modified files:
	gcc            : ChangeLog gimplify.c 

Log message:
	PR mudflap/19319, c++/19317
	* gimplify.c (gimplify_modify_expr_rhs) [CALL_EXPR]: Make return
	slot explicit.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.7504&r2=2.7505
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/gimplify.c.diff?cvsroot=gcc&r1=2.111&r2=2.112

Comment 9 Andrew Pinski 2005-02-19 15:56:38 UTC
Reopening as the patch had to be reverted.
Comment 10 Frank Ch. Eigler 2005-03-10 21:57:40 UTC
Myseriously, the bug still appears fixed, in both 4_0-branch and mainline,
despite the reversion.  See libmudflap/testsuite/*++/pass55*. For archival
purposes, the last approved but apparently unnecessary patch for this
problem was this one:

http://gcc.gnu.org/ml/gcc-patches/2005-03/msg00381.html
Comment 11 Gideon Amos 2005-08-18 19:57:47 UTC
I'm still getting a mudflap violation with the simpler test case, posted by
Frank Ch. Eigler, I get this on a debian linux system (Linux version
2.6.8-1-686-smp) with at least two builds of gcc:

$ gcc --version 
gcc (GCC) 4.0.1
[...]
$ gcc -dumpmachine
target i686-pc-linux-gnu 

and

$ gcc-4.0 --version
gcc-4.0 (GCC) 4.0.2 20050816 (prerelease) (Debian 4.0.1-5)
[...]
$ gcc-4.0 -dumpmachine
i486-linux-gnu

Comment 12 Frank Ch. Eigler 2005-08-18 20:05:31 UTC
still broken.
Comment 13 Frank Ch. Eigler 2005-09-23 21:35:19 UTC
I can't explain it, but on today's mainline, this bug does not appear.  I'm
going to commit the smaller test case ("... make_k ...") from above to
libmudflap/testsuite.  If this test fails, please post an attachment with the
error log.  Since neither my x86 nor x86-64 machine shows the problem, it may be
necessary for you to rebuild the test case with extra dump flags
("-fdump-tree-all" and friends) and scour through that for clues.
Comment 14 CVS Commits 2005-09-23 21:35:23 UTC
Subject: Bug 19319

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	fche@gcc.gnu.org	2005-09-23 21:35:17

Modified files:
	libmudflap     : ChangeLog 
Added files:
	libmudflap/testsuite/libmudflap.c++: pass58-frag.cxx 

Log message:
	2005-09-23  Frank Ch. Eigler  <fche@elastic.org>
	
	* testsuite/libmudflap.c++/pass58-frag.cxx: New test for heisenbug 19319.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libmudflap/ChangeLog.diff?cvsroot=gcc&r1=1.71&r2=1.72
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libmudflap/testsuite/libmudflap.c++/pass58-frag.cxx.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 15 Paul Pluzhnikov 2005-10-23 23:47:10 UTC
On "stock" FC2, using the latest gcc-4.1 snapshot (20051022), I get 7 mudflap
violations from the original test, 1 from the reduced test.

This doesn't appear to be a heisenbug at all -- it reproduces with all
gcc-4.x releases/snapshots on all i686 systems I tried!
Comment 16 Paul Pluzhnikov 2005-12-14 17:46:27 UTC
Same picture using gcc-4.1-20051209 for i686-pc-linux-gnu: 
7 bogus violations on original test, 1 on reduced test.

Here are other version results:
                                               original           reduced
gcc-4.1-20051209 i686-pc-linux-gnu               7                   1
gcc-4.2-20051210 i686-pc-linux-gnu               1                   1
gcc-4.2-20051210 x86_64-unknown-linux-gnu        0                   0
gcc-4.2-20051210 x86_64-unknown-linux-gnu -m32   1                   1

Encouraged by the absence of bogus warnings on x86_64 in 64-bit mode, I tried 
4.2-20051210 on my real code. This resulted in 100s of bogus violations,
though I have not been able to produce a reduced test case yet :-(

I then tried 4.2-20051210 i686 on "pure C" real code, and got 100s more
bogus violations.

IMHO, the -fmudflap either needs to be made to work correctly on real C/C++
programs, or it should be removed altogether (bogus reports lead to a lot
of wasted time, as each new user "discovers" the feature, and then finds out
it doesn't work).
Comment 17 Andrew Pinski 2006-03-19 05:11:47 UTC
NVR in the C++ front-end is causing this violation to be produced.
Comment 18 Frank Ch. Eigler 2006-11-10 03:09:03 UTC
For what it's worth, this problem does not appear to show up in current mainline
gcc.  If indeed it was caused by tree-ssa passes other than mudflap itself,
a backport of whatever is making it work now seems very unlikely.
Comment 19 p.van-hoof 2006-11-10 16:33:50 UTC
The reduced testcases listed previously in this thread indeed work correctly on the mainline, but a real C++ program that I tested still spewed thousands of violations, although valgrind could not find anything. The attached test case test.cc is one such example. Note that the test program tries to read its own source, so don't rename the file!

> g++ -fmudflap test.cc -lmudflap
> a.out
*******
mudflap violation 1 (check/read): time=1163175853.725925 ptr=0x2ac0ae8ee720 size=8
pc=0x2ac0ae464871 location=`test.cc:18 (main)'
      /usr/local/gcc430/lib64/libmudflap.so.0(__mf_check+0x41) [0x2ac0ae464871]
      a.out(main+0x219) [0x40133d]
      /lib64/libc.so.6(__libc_start_main+0xf4) [0x2ac0aeb88154]
number of nearby objects: 0
> g++ -v
Using built-in specs.
Target: x86_64-unknown-linux-gnu
Configured with: /dump1/root/temp/gcc/configure --prefix=/usr/local/gcc430 --enable-languages=c,c++,fortran
Thread model: posix
gcc version 4.3.0 20061030 (experimental)
Comment 20 p.van-hoof 2006-11-10 16:35:11 UTC
Created attachment 12588 [details]
test case mentioned in Comment #19
Comment 21 Paul Pluzhnikov 2006-11-10 23:00:40 UTC
I was going to say the same thing, but p.van-hoof beat me to it.

Here is another trivial test case that shows 1 violation:

// Reduced from ex02-04.cpp from "STL Tutorial and Reference Guide"
#include <string>
using namespace std; 

int main()
{
  map<string, long> directory;
  directory["Bogart"] = 1234567;
  directory["Bacall"] = 9876543;
}

The violation was reproduced with gcc-4.3-20061104 snapshot on linux-i686.
Comment 22 Paul Pluzhnikov 2006-11-10 23:30:56 UTC
I missed '#include <map>' in comment 21 above (sorry for cut/paste error).

As I said in comment 16, this problem isn't limited to C++ code either.
Instrument gmake-3.81, and you'll get 100,000+ violations
Comment 23 Frank Ch. Eigler 2006-11-14 03:53:24 UTC
 As I said in comment 16, this problem isn't limited to C++ code either.
> Instrument gmake-3.81, and you'll get 100,000+ violations

Sorry, I don't see that.
configured gnu make 3.81
compiled with mainline, CFLAGS="-fmudflap" LDFLAGS="-lmudflap".
ran resulting executable.  No problems at all, just slower.
Tried again with "-O2 -fmudflap".  Same result.
Comment 24 Paul Pluzhnikov 2006-11-14 04:26:24 UTC
Created attachment 12615 [details]
annotated transcript

Might the problem be that I am compiling on an "old" glibc?
Or that you didn't invoke ./make and didn't in fact run the resulting exe?
Comment 25 Frank Ch. Eigler 2006-11-14 12:19:00 UTC
(In reply to comment #24)
> Might the problem be that I am compiling on an "old" glibc?

That is possible.  Try MUDFLAP_OPTIONS="-trace-calls -verbose-trace".
If you have access to a modern glibc, you could compare traces from the two
variants.

> Or that you didn't invoke ./make and didn't in fact run the resulting exe?
 
I certainly ran it.  "env MUDFLAP_OPTIONS=-collect-stats ./make" gives some
interesting figures.
Comment 26 Paul Pluzhnikov 2006-11-15 01:22:42 UTC
(In reply to comment 25)

Confirmed: using newer glibc:
 GNU C Library development release version 2.3.5, by Roland McGrath et al.
and having rebuilt gcc-4.3-20061104 on it, I do not see violations on
make-3.81

Confirmed: the test case from comment 21 still shows 1 violation.

---------------------------------------------------------
I also tracked down the violations I see on glibc-2.1.3
Here is the smallest test case:

#include <ctype.h>

int main()
{
   const char *p = "a";
   return isblank(*p);
}

When compiled with '-fmudflap' there are no violations.
When compiled with '-fmudflap -D_GNU_SOURCE', there is a violation:
*******
mudflap violation 1 (check/read): time=1163551808.269474 ptr=0x3feeb302 size=2
pc=0x3ff0d2fd location=`junk.c:6 (main)'
      /usr/local/gcc-4.3-20061104/lib/libmudflap.so.0(__mf_check+0x3d) [0x3ff0d2fd]
      [0x8048850]
      /usr/local/gcc-4.3-20061104/lib/libmudflap.so.0(__wrap_main+0x49) [0x3ff0cdb9]
number of nearby objects: 0

In the first case, isblank() expands to call to isblank().
In the second, it expands into 
  (__ctype_b[(int) ((*p))] & (unsigned short int) _ISblank)

And libmudflap (apparently) doesn't understand where __ctype_b
is pointing at. In fact, here is reduced test case that shows
the exact same problem regardless of glibc version:

$ cat junk1.c
extern int *array;
int main()
{
    return array[0];
}

$ cat junk2.c
int _array[1];
int *array = _array;

$ gcc -g -c junk2.c && 
  gcc -g -fmudflap junk1.c junk2.o -lmudflap \
   -Wl,-rpath=/usr/local/gcc-4.3-20061104/lib && ./a.out
*******
mudflap violation 1 (check/read): time=1163552372.861362 ptr=0x80c9998 size=4
pc=0xe6d1bd location=`junk1.c:4 (main)'
      /usr/local/gcc-4.3-20061104/lib/libmudflap.so.0(__mf_check+0x3d) [0xe6d1bd]
      ./a.out(main+0x84) [0x8048748]
      /usr/local/gcc-4.3-20061104/lib/libmudflap.so.0(__wrap_main+0x49) [0xe6cc79]
Nearby object 1: checked region begins 8B after and ends 11B after
mudflap object 0x80ca0f8: name=`__mf_lc_shift'
bounds=[0x80c9990,0x80c9990] size=1 area=no-access check=0r/0w liveness=0
alloc time=1163552372.860997 pc=0xe6cc1d
Nearby object 2: checked region begins 9B after and ends 12B after
mudflap object 0x80ca028: name=`__mf_lookup_cache'
bounds=[0x8049990,0x80c998f] size=524288 area=no-access check=0r/0w liveness=0
alloc time=1163552372.860984 pc=0xe6cc1d
number of nearby objects: 2

The above violation goes away when I add
MUDFLAP_OPTIONS=-heur-start-end, and gmake-3.81 violations go away
when I add MUDFLAP_OPTIONS=-heur-proc-map but I had to dig up the
original mudflap design article:
  http://gcc.fyxm.net/summit/2003/mudflap.pdf
to figure this out.

If you expect your future users to figure this out, I've got a
surprise for you: they most likely will not. These heuristics
probably should be enabled by default (at least on Linux), or at
least *prominently* displayed in the info/man pages.
Comment 27 Alex Lamaison 2007-06-10 19:32:35 UTC
I have been writing my own bounds-checker based on Mudflap.  While doing so I had to tackle this same problem.  My flatmate and I tracked it down to the fact that, although function parameters and variables are registered if their address is ever taken, the return value is not.  This is a problem in return-by-value where the result is returned directly without an intermediate variable.  For example:

class bob {
  public:
    int i;
    bob(int n) { i = n; }
};

bob f(int n)
{
  return bob(n);
}

int main()
{
  bob b = f(0);
}

Here bob is constructed directly in the return statement in f().  In GIMPLE this looks like:

bob f(int) (n)
{
<bb 0>:
  __comp_ctor  (&<retval>, n);
  return <retval>;
}

Notice that <retval> has its address taken.  Inside the constructor __comp_ctor() the object is created in the location given by <retval>.
<retval> has not been registered by f() as return values are not registered, nor has it been registered by main() (where the object finally ends up) because nothing there uses its address.  

This happens a lot in the STL, hence why it shows up whenever template, map etc., are used:

iterator begin()
{
    return iterator (this->_M_impl._M_start);
}

which is gimplified to into:

iterator begin()
{
    comp_ctor (&<retval>, &this->_M_impl._M_start);
    return <retval>;
} 

If Mudflap is changed to register these return values, the violations go away :)  I have created a patch that does this but, as I'm a relative newbie, it could all be complete rubbish in which case I apologise.

This deals with the problem for the initial testcase, the simplified test by Frank Ch. Eigler and the test by Paul Pluzhnikov.  It does not fix the others as these are caused by a different problem, namely objects created by external library calls are not registered by Mudflap and so it thinks there is a violation if you use one of these foreign pointers.

I hope this helps and I would be very glad of feedback.

Alex Lamaison
Comment 28 Alex Lamaison 2007-06-10 19:35:31 UTC
Created attachment 13673 [details]
Patch for tree-mudflap.c

This is the patch mentioned in my explanation.  It is against the 4.1.1 release source.
Comment 29 Frank Ch. Eigler 2007-06-20 19:37:11 UTC
> This is the patch mentioned in my explanation.  It is against the 4.1.1 release
> source.

Thanks!
This patch applies fine to CVS head, but it does not appear to help significantly
with the C++ test cases like the ones in the test suite.
Comment 30 Alex Lamaison 2007-07-12 23:58:45 UTC
> This patch applies fine to CVS head, but it does not appear to help
> significantly with the C++ test cases like the ones in the test suite.

If I run the pass58-frag.cxx test case without the patch it produces the following:

*******
mudflap violation 1 (check/write): time=1184284085.501231 ptr=0xbf9fb160 size=4
pc=0xb7e2a31d location=`mudflap-pass58.cpp:3 (k::k)'
      /var/home/awl03/Project/trunk/install/usr/local/lib/libmudflap.so.0(__mf_check+0x3d) [0xb7e2a31d]
      ./mudflap-pass58-cpp(_ZN1kC1Ei+0x6f) [0x80487e7]
      ./mudflap-pass58-cpp(_Z6make_kv+0x1a) [0x804872e]
... etc.

But if I apply the path the same test executes without a problem.  Are there other C++ test cases that still don't work properly?
Comment 31 Jason Merrill 2007-08-27 18:41:42 UTC
It seems that G++ is setting TREE_ADDRESSABLE on the RETURN_DECL properly, so the remaining problem is in the mudflap code.  Reassigning to fche.
Comment 32 Frank Ch. Eigler 2008-04-09 19:15:03 UTC
The patch has been committed for some time, and this test case passes.
Comment 33 Florian Knauf 2009-05-07 00:18:43 UTC
This still doesn't seem to be entirely fixed. The following program:

#include <map>

int main() {
  std::map<int, int> m;
  m[123] = 123;
  m[234] = 234;
}

compiled on debian/x86 with gcc 4.4.0 (with -fmudflap and -lmudflap, no other options) yields the following mudflap errors:

*******
mudflap violation 1 (check/write): time=1241654029.990933 ptr=0xbfc08b0c size=4
pc=0xb7dfb37d location=`/usr/include/c++/4.4/bits/stl_tree.h:171:20 (std::_Rb_tree_iterator<std::pair<const int, int> >::_Rb_tree_iterator)'
      /usr/lib/libmudflap.so.0(__mf_check+0x3d) [0xb7dfb37d]
      ./a.out(_ZNSt17_Rb_tree_iteratorISt4pairIKiiEEC1EPSt13_Rb_tree_nodeIS2_E+0x70) [0x804c836]
      ./a.out(_ZNSt8_Rb_treeIiSt4pairIKiiESt10_Select1stIS2_ESt4lessIiESaIS2_EE10_M_insert_EPKSt18_Rb_tree_node_baseSB_RKS2_+0x1ba) [0x804cb12]
Nearby object 1: checked region begins 17B after and ends 20B after
mudflap object 0x9b54ed0: name=`/usr/include/c++/4.4/bits/stl_map.h:539:23 (std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >::insert) std::_Rb_tree\
_iterator<std::pair<const int, int> > __position'
bounds=[0xbfc08af8,0xbfc08afb] size=4 area=stack check=1r/0w liveness=1
alloc time=1241654029.990826 pc=0xb7dfab1d
Nearby object 2: checked region begins 12B before and ends 9B before
mudflap object 0x9b54de0: name=`/usr/include/c++/4.4/bits/stl_map.h:447:11 (std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >::operator[]) std::_Rb_\
tree_iterator<std::pair<const int, int> > __i'
bounds=[0xbfc08b18,0xbfc08b1b] size=4 area=stack check=0r/1w liveness=1
alloc time=1241654029.990818 pc=0xb7dfab1d
Nearby object 3: checked region begins 16B before and ends 13B before
mudflap object 0x9b54ca0: name=`/usr/include/c++/4.4/bits/stl_map.h:449:2 (std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >::operator[]) <unnamed v\
ariable>'
bounds=[0xbfc08b1c,0xbfc08b1f] size=4 area=stack check=0r/1w liveness=1
alloc time=1241654029.990814 pc=0xb7dfab1d
Nearby object 5: checked region begins 12B before and ends 9B before
mudflap dead object 0x9b54108: name=`/usr/include/c++/4.4/bits/stl_map.h:447:11 (std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >::operator[]) std:\
:_Rb_tree_iterator<std::pair<const int, int> > __i'
bounds=[0xbfc08b18,0xbfc08b1b] size=4 area=stack check=0r/1w liveness=1
alloc time=1241654029.990541 pc=0xb7dfab1d
dealloc time=1241654029.990812 pc=0xb7dfa6a6
Nearby object 6: checked region begins 23B before and ends 20B before
mudflap dead object 0x9b53fd0: name=`/usr/include/c++/4.4/bits/stl_map.h:449:2 (std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >::operator[]) <unna\
med variable>'
bounds=[0xbfc08b23,0xbfc08b23] size=1 area=stack check=0r/0w liveness=0
alloc time=1241654029.990539 pc=0xb7dfab1d
dealloc time=1241654029.990810 pc=0xb7dfa6a6
number of nearby objects: 6

Compiled with gcc 4.3.3 it yields similar errors (only some line numbers changed). The weird thing is that this bit:

#include <map>

int main() {
  std::map<int, int> m;
  m[123] = 123;
}

doesn't produce any mudflap errors at all. The even weirder thing is that I can't get these errors to show with the first (or any more complicated) program on x86-64.

I haven't yet been able to produce a simpler test case for this, but I'll keep trying. Also, I'll try to confirm this for sparc-sun-solaris2.8, although it may be a few days before I'm able to do that.
Comment 34 Florian Knauf 2009-05-07 16:30:52 UTC
I can confirm the behaviour for sparc-sun-solaris2.8, the first program mentioned in the last comment complains as follows:

*******
mudflap violation 1 (check/write): time=1241712982.495997 ptr=ffbefac4 size=4
pc=ff288ac8 location=`/usr/local/lib/gcc/sparc-sun-solaris2.8/4.4.0/../../../../sparc-sun-solaris2.8/include/c++/4.4.0/bits/stl_tree.h:171:20 (std::_Rb_tree_iterator<std::pair<const int, int> >::_Rb_tree_iterator)'
      [0xff2876f0]
Nearby object 1: checked region begins 1B after and ends 4B after
mudflap object af548: name=`/usr/local/lib/gcc/sparc-sun-solaris2.8/4.4.0/../../../../sparc-sun-solaris2.8/include/c++/4.4.0/bits/stl_map.h:539:23 (std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >::insert) std::_Rb_tree_iterator<std::pair<const int, int> > __position'
bounds=[ffbefac0,ffbefac3] size=4 area=stack check=1r/0w liveness=1
alloc time=1241712982.495900 pc=ff2881a4
Nearby object 2: checked region begins 4B before and ends 1B before
mudflap object af440: name=`/usr/local/lib/gcc/sparc-sun-solaris2.8/4.4.0/../../../../sparc-sun-solaris2.8/include/c++/4.4.0/bits/stl_map.h:447:11 (std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >::operator[]) std::_Rb_tree_iterator<std::pair<const int, int> > __i'
bounds=[ffbefac8,ffbefacb] size=4 area=stack check=0r/1w liveness=1
alloc time=1241712982.495875 pc=ff2881a4
Nearby object 3: checked region begins 4B before and ends 1B before
mudflap dead object adc00: name=`/usr/local/lib/gcc/sparc-sun-solaris2.8/4.4.0/../../../../sparc-sun-solaris2.8/include/c++/4.4.0/bits/stl_map.h:447:11 (std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >::operator[]) std::_Rb_tree_iterator<std::pair<const int, int> > __i'
bounds=[ffbefac8,ffbefacb] size=4 area=stack check=0r/1w liveness=1
alloc time=1241712982.495593 pc=ff2881a4
dealloc time=1241712982.495861 pc=ff287d58
number of nearby objects: 3

I compiled it with a gcc 4.4.0 cross compiler from i486-linux-gnu to sparc-sun-solaris2.8 (sparcv8), compiler options -fmudflap -lmudflap -lsocket (the last one being necessary to link mudflap). I had to remove the getmntent wrapper from the mudflap library because solaris 2.8 uses an interface different from the one gcc expects. Other than that, the gcc sources the compiler was built from were unchanged.

As on x86, the same program compiled with the same options plus -m64 (i.e., for sparcv9) yields no mudflap errors.
Comment 35 Jackie Rosen 2014-02-16 09:59:26 UTC Comment hidden (spam)