bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

More complete fix for a previous problem in gprof.


From: David Warme
Subject: More complete fix for a previous problem in gprof.
Date: Mon, 6 Jun 2011 16:56:14 -0400 (EDT)

Here is a patch to correct a previous gprof bug that was only partially
fixed.  Apparently it is possible for GCC to clone its own cloned
functions.

This problem manifested in a large g++ application which I cannot
provide in source form.  Furthermore, simplification of that example
eliminates the problem with high probability.  The best evidence I can
provide is the following gdb session showing the boundary between two
functions that demonstrates such a "clone of a clone":

(gdb) x/5i 0x7a7ae8
0x7a7ae8 <_ZN10sims_Event15startSimulationEv+552>:
    callq  0x7a6f40 <_ZN19trno_WarningMessagelsEPKc.clone.4>
0x7a7aed <_ZN10sims_Event15startSimulationEv+557>:
    jmp    0x7a7ab8 <_ZN10sims_Event15startSimulationEv+504>
0x7a7aef:       nop    
0x7a7af0 
<_ZNKSt6vectorIPN10sims_Event9EventLinkESaIS2_EE12_M_check_lenEmPKc.clone.45.clone.53>:
        push   %rbp
0x7a7af1 
<_ZNKSt6vectorIPN10sims_Event9EventLinkESaIS2_EE12_M_check_lenEmPKc.clone.45.clone.53+1>:
      mov    %rsp,%rbp
(gdb)

Note the .clone.45.clone.53 suffix on the symbol.

The following patch accepts function symbols that match the following
extended regular expression:

        ^[^\$\.]*(\.(clone\.)?[0-9]+)+$

and so accepts the following symbols:

        foo.123
        foo.clone.23
        foo.clone.1.clone.2
        foo.2.clone.6.clone.9
        foo.2.1.clone.3.4.clone.5

This errs on the side of accepting more cases than the relevent
mechanisms are likely to produce (e.g., the last example).

David

--- orig/gprof/corefile.c       2011-06-06 10:07:57.406964819 -0400
+++ fixed/gprof/corefile.c      2011-06-06 10:15:10.198544726 -0400
@@ -389,16 +389,21 @@
 
       if (*name == '.')
        {
-         /* Allow GCC cloned functions.  */
-         if (strlen (name) > 7 && strncmp (name, ".clone.", 7) == 0)
-           name += 6;
-
-         /* Do not discard nested subprograms (those
-            which end with .NNN, where N are digits).  */
-         for (name++; *name; name++)
-           if (! ISDIGIT (*name))
+         /* Allow both nested subprograms and GCC cloned functions.
+            Apparently, GCC can clone both of these. */
+         do {
+           if (strlen (name) > 7 && strncmp (name, ".clone.", 7) == 0)
+             name += 6;
+           int digit_seen = 0;
+           /* Do not discard nested subprograms (those
+              which end with .NNN, where N are digits).  */
+           for (name++; *name; name++)
+             if (digit_seen && *name == '.') break;
+             else if (ISDIGIT (*name))
+               digit_seen = 1;
+             else
              return 0;
-
+         } while (*name == '.');
          break;
        }
     }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]