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; } } _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org https://lists.gnu.org/mailman/listinfo/bug-binutils