]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 469146 - massif --ignore-fn does not ignore inlined functions
authorPaul Floyd <pjfloyd@wanadoo.fr>
Sat, 6 May 2023 05:45:47 +0000 (07:45 +0200)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Sat, 6 May 2023 05:45:47 +0000 (07:45 +0200)
.gitignore
NEWS
coregrind/m_debuginfo/debuginfo.c
include/pub_tool_debuginfo.h
massif/docs/ms-manual.xml
massif/ms_main.c
massif/tests/Makefile.am
massif/tests/bug469146.cpp [new file with mode: 0644]
massif/tests/bug469146.post.exp [new file with mode: 0644]
massif/tests/bug469146.stderr.exp [new file with mode: 0644]
massif/tests/bug469146.vgtest [new file with mode: 0644]

index 6155f8f355a5ae505bd39dbddb7d4f7883652749..076e168deda4e1e092be74f56bbbd5357988f27f 100644 (file)
 /massif/tests/basic
 /massif/tests/basic_malloc
 /massif/tests/big-alloc
+/massif/tests/bug469146
 /massif/tests/culling1
 /massif/tests/culling2
 /massif/tests/custom_alloc
diff --git a/NEWS b/NEWS
index e269d128b98ad6b65bbd3ff2a8d50106bbf61676..f44cfde1dcb67ea2a2fd92d80f69ed6d12437f48 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -26,7 +26,7 @@ bugzilla (https://bugs.kde.org/enter_bug.cgi?product=valgrind) rather
 than mailing the developers (or mailing lists) directly -- bugs that
 are not entered into bugzilla tend to get forgotten about or ignored.
 
-
+469146  massif --ignore-fn does not ignore inlined functions
 
 To see details of a given bug, visit
   https://bugs.kde.org/show_bug.cgi?id=XXXXXX
index 2d2accc999ea31e88ec578711358f8cfd011fac7..22b41def211b08a745e7aa630b093e5a8bc92ae3 100644 (file)
@@ -2289,6 +2289,32 @@ Bool VG_(get_fnname) ( DiEpoch ep, Addr a, const HChar** buf )
                          /*offsetP*/NULL );
 }
 
+
+Bool VG_(get_fnname_inl) ( DiEpoch ep, Addr a, const HChar** buf,
+                                   const InlIPCursor* iipc )
+{
+   if (iipc) {
+      vg_assert(is_DI_valid_for_epoch(iipc->di, ep));
+   }
+
+   if (is_bottom(iipc)) {
+      return get_sym_name ( /*C++-demangle*/True, /*Z-demangle*/True,
+                            /*below-main-renaming*/True,
+                            ep, a, buf,
+                            /*match_anywhere_in_fun*/True,
+                            /*show offset?*/False,
+                            /*text sym*/True,
+                            /*offsetP*/NULL );
+   } else {
+      const DiInlLoc *next_inl = iipc && iipc->next_inltab >= 0
+         ? & iipc->di->inltab[iipc->next_inltab]
+         : NULL;
+      vg_assert (next_inl);
+      *buf = next_inl->inlinedfn;
+      return True;
+   }
+}
+
 /* This is available to tools... always demangle C++ names,
    match anywhere in function, and show offset if nonzero.
    NOTE: See IMPORTANT COMMENT above about persistence and ownership
index 078c562b8ed3989d04a779382bf7ede5fe62ac64..7631ff67a675ec35fd1c9cd3b3bbb213bd2977a1 100644 (file)
@@ -210,7 +210,9 @@ extern Bool VG_(next_IIPC)(InlIPCursor *iipc);
 /* Free all memory associated with iipc. */
 extern void VG_(delete_IIPC)(InlIPCursor *iipc);
 
-
+/* Similar to  VG_(get_fnname) but uses InlIPCursor and handles inline functions */
+extern Bool VG_(get_fnname_inl)   ( DiEpoch ep, Addr a, const HChar** fnname,
+                                   const InlIPCursor* iipc );
 
 /* Get an XArray of StackBlock which describe the stack (auto) blocks
    for this ip.  The caller is expected to free the XArray at some
index b589071556f61ede391d7fcc4bbd753c33f27cf0..3dff2599523a64b56b901ae8c989f369144a37bc 100644 (file)
@@ -760,6 +760,17 @@ various places online.
 <screen><![CDATA[
 --alloc-fn='operator new(unsigned, std::nothrow_t const&)'
 ]]></screen>
+      Arguments of type <computeroutput>size_t</computeroutput> need to be replaced
+      with <computeroutput>unsigned long</computeroutput> on 64bit platforms and <computeroutput>unsigned</computeroutput>
+      on 32bit platforms.
+      </para>
+
+      <para><option>--alloc-fn</option> will work with inline functions.
+      Inline function names are not mangled, which means that you only need
+      to provide the function name and not the argument list.
+      </para>
+
+      <para><option>--alloc-fn</option> does not support wildcards.
       </para>
       </listitem>
   </varlistentry>
index f3500c367d4adebdebbfa10d783fa43e29225790..1040ad53f4b2afca1ec31554a320a3cced7b542d 100644 (file)
@@ -506,6 +506,8 @@ void filter_IPs (Addr* ips, Int n_ips,
 {
    Int i;
    Bool top_has_fnname = False;
+   Bool is_alloc_fn = False;
+   Bool is_inline_fn = False;
    const HChar *fnname;
 
    *top = 0;
@@ -519,9 +521,21 @@ void filter_IPs (Addr* ips, Int n_ips,
    //    0x1 0x2 0x3 alloc func1 main
    //  became   0x1 0x2 0x3 func1 main
    const DiEpoch ep = VG_(current_DiEpoch)();
-   for (i = *top; i < n_ips; i++) {
-      top_has_fnname = VG_(get_fnname)(ep, ips[*top], &fnname);
-      if (top_has_fnname &&  VG_(strIsMemberXA)(alloc_fns, fnname)) {
+   InlIPCursor *iipc = NULL;
+
+   for (i = *top; i < n_ips; ++i) {
+      iipc = VG_(new_IIPC)(ep, ips[i]);
+      do {
+         top_has_fnname = VG_(get_fnname_inl)(ep, ips[i], &fnname, iipc);
+         is_alloc_fn = top_has_fnname && VG_(strIsMemberXA)(alloc_fns, fnname);
+         is_inline_fn = VG_(next_IIPC)(iipc);
+         if (is_alloc_fn && is_inline_fn) {
+            VERB(4, "filtering inline alloc fn %s\n", fnname);
+         }
+      } while (is_alloc_fn && is_inline_fn);
+      VG_(delete_IIPC)(iipc);
+
+      if (is_alloc_fn) {
          VERB(4, "filtering alloc fn %s\n", fnname);
          (*top)++;
          (*n_ips_sel)--;
@@ -534,8 +548,15 @@ void filter_IPs (Addr* ips, Int n_ips,
    if (*n_ips_sel > 0 && VG_(sizeXA)(ignore_fns) > 0) {
       if (!top_has_fnname) {
          // top has no fnname => search for the first entry that has a fnname
-         for (i = *top; i < n_ips && !top_has_fnname; i++) {
-            top_has_fnname = VG_(get_fnname)(ep, ips[i], &fnname);
+         for (i = *top; i < n_ips && !top_has_fnname; ++i) {
+            iipc = VG_(new_IIPC)(ep, ips[i]);
+            do {
+               top_has_fnname = VG_(get_fnname_inl)(ep, ips[i], &fnname, iipc);
+               if (top_has_fnname) {
+                  break;
+               }
+            } while (VG_(next_IIPC)(iipc));
+            VG_(delete_IIPC)(iipc);
          }
       }
       if (top_has_fnname && VG_(strIsMemberXA)(ignore_fns, fnname)) {
index 84c9b1273ad6f165cc7ff69f091ba8b7a3ee70bc..2f3a84ecc7eba3fe2b8dd9d6c2cb1fa1fa4856ce 100644 (file)
@@ -11,6 +11,7 @@ EXTRA_DIST = \
        big-alloc.post.exp big-alloc.post.exp-64bit big-alloc.post.exp-ppc64 \
        big-alloc.stderr.exp big-alloc.vgtest \
        big-alloc.post.exp-x86-freebsd \
+       bug469146.post.exp bug469146.stderr.exp bug469146.vgtest \
        deep-A.post.exp deep-A.stderr.exp deep-A.vgtest \
        deep-B.post.exp deep-B.stderr.exp deep-B.vgtest \
        deep-C.post.exp deep-C.stderr.exp deep-C.vgtest \
@@ -59,6 +60,7 @@ check_PROGRAMS = \
        alloc-fns \
        basic \
        big-alloc \
+       bug469146 \
        culling1 culling2 \
        custom_alloc \
        deep \
@@ -86,6 +88,8 @@ AM_CFLAGS   += $(AM_FLAG_M3264_PRI)
 AM_CXXFLAGS += $(AM_FLAG_M3264_PRI)
 
 # C++ tests
+bug469146_SOURCES      = bug469146.cpp
+bug469146_CXXFLAGS     = $(AM_CFLAGS) -O2
 new_cpp_SOURCES                = new-cpp.cpp
 overloaded_new_SOURCES = overloaded-new.cpp
 # pre C++11 compilers don't have exception specs
diff --git a/massif/tests/bug469146.cpp b/massif/tests/bug469146.cpp
new file mode 100644 (file)
index 0000000..268f07c
--- /dev/null
@@ -0,0 +1,41 @@
+#include <cstdlib>
+
+// this is inline so it filters as "filter_function1"
+static inline int* filter_function1(std::size_t size)
+{
+   return new int[size];
+}
+
+// this is out of line C++
+// int is deliberately used here instead of size_t
+// so that it is 32/b4 bit portable
+// this filters as "filter_function2(int)"
+int* __attribute__((optnone)) __attribute__((noinline)) filter_function2(int size)
+{
+   return new int[static_cast<std::size_t>(size)];
+}
+
+// finally extern "C"
+// this filters as "filter_function3"
+extern "C"
+int*  __attribute__((optnone)) __attribute__((noinline)) filter_function3(std::size_t size)
+{
+   return new int[size];
+}
+
+size_t func()
+{
+   int * mem1 = filter_function1(1000U);
+   int * mem2 = filter_function2(1000);
+   int * mem3 = filter_function3(1000U);
+   delete [] mem1;
+   delete [] mem2;
+   delete [] mem3;
+   
+   return (size_t)mem1/2 + (size_t)mem2/2 + (size_t)mem3/2;
+}
+
+int main()
+{
+   return func();
+}
diff --git a/massif/tests/bug469146.post.exp b/massif/tests/bug469146.post.exp
new file mode 100644 (file)
index 0000000..1e9936c
--- /dev/null
@@ -0,0 +1,38 @@
+--------------------------------------------------------------------------------
+Command:            ./bug469146
+Massif arguments:   --stacks=no --time-unit=B --massif-out-file=massif.out --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook --ignore-fn=get_or_create_key_element --ignore-fn=_GLOBAL__sub_I_eh_alloc.cc --ignore-fn=call_init.part.0 --ignore-fn=call_init --ignore-fn=filter_function1 --ignore-fn=filter_function2(int) --ignore-fn=filter_function3
+ms_print arguments: massif.out
+--------------------------------------------------------------------------------
+
+
+     B
+    1^                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+     |                                                                        
+   0 +----------------------------------------------------------------------->B
+     0                                                                       1
+
+Number of snapshots: 1
+ Detailed snapshots: []
+
+--------------------------------------------------------------------------------
+  n        time(B)         total(B)   useful-heap(B) extra-heap(B)    stacks(B)
+--------------------------------------------------------------------------------
+  0              0                0                0             0            0
diff --git a/massif/tests/bug469146.stderr.exp b/massif/tests/bug469146.stderr.exp
new file mode 100644 (file)
index 0000000..139597f
--- /dev/null
@@ -0,0 +1,2 @@
+
+
diff --git a/massif/tests/bug469146.vgtest b/massif/tests/bug469146.vgtest
new file mode 100644 (file)
index 0000000..68585a4
--- /dev/null
@@ -0,0 +1,8 @@
+prog: bug469146
+vgopts: --stacks=no --time-unit=B --massif-out-file=massif.out
+vgopts: --ignore-fn=__part_load_locale --ignore-fn=__time_load_locale --ignore-fn=dwarf2_unwind_dyld_add_image_hook
+vgopts: --ignore-fn=get_or_create_key_element --ignore-fn=_GLOBAL__sub_I_eh_alloc.cc --ignore-fn=call_init.part.0
+vgopts: --ignore-fn=call_init
+vgopts: --ignore-fn=filter_function1 --ignore-fn="filter_function2(int)" --ignore-fn=filter_function3
+post: perl ../../massif/ms_print massif.out | sed 's/gcc[0-9]*/gcc/' | ../../tests/filter_addresses
+cleanup: rm massif.out