2015-12-11 29 views
6

मैं this सीपीपीकॉन 2015 से बात करने के बाद कुछ कार्यक्रमों को प्रोफाइल करने के लिए एक शॉट देना चाहता था। मैंने उसी Google बेंचमार्क लाइब्रेरी को डाउनलोड किया जो लड़का इस बात का उपयोग करता है, मेरे प्रोग्राम को उचित स्विच के साथ संकलित करता है , इसे इसके साथ जोड़ा, फिर एक रन रिकॉर्ड करने के लिए perf इस्तेमाल किया। इस रिपोर्ट विकल्प मेरे देता है:पेर्फ मैंगल्ड फ़ंक्शन नाम दिखाता है

enter image description here

आप फ़ंक्शन नाम बहुत पढ़ने योग्य नहीं हैं देख सकते हैं। मुझे लगता है कि इसे सी ++ नाम मैंगलिंग के साथ करना है। दिलचस्प बात यह है कि वीडियो के सभी समारोह नाम उस व्यक्ति के लिए सही तरीके से दिखाए जाते हैं जिसने बात की, लेकिन मेरे लिए नहीं। मुझे नहीं लगता कि यह प्रतीक जानकारी पूरी तरह गायब होने का मामला है क्योंकि मुझे उस मामले में केवल स्मृति पते दिखाई देंगे। किसी कारण से, perf मेरे लिए C++ नाम मैंगलिंग को "पूर्ववत" नहीं कर सकता है, और यह देखने के लिए निराशाजनक है।

मैं उपयोग कर रहा हूँ जीसीसी (छ ++), संस्करण 5.2.1, पर्फ़ संस्करण 4.2.6 है, और मैं जब संकलन इन स्विच का उपयोग करें:

-I<my own include path> -L<path to the benchmark library> -O3 -std=c++14 -gdwarf-2 -fno-rtti -Wall -pedantic -lbenchmark -pthread

कारण है कि मैं -fno-omit-frame-pointer का उपयोग नहीं करते यह है कि मैं इसके बजाय -gdwarf-2 विकल्प का उपयोग करता हूं, जो बौने निष्पादन योग्य में डीबगिंग जानकारी छोड़ देता है, जो इस मामले में फ्रेम पॉइंटर को छोड़ने का विकल्प है। इसका मतलब यह भी है कि मैं --call-graph "dwarf" से perf record पास करता हूं। वैसे भी, मैंने फ्रेम पॉइंटर विधि भी कोशिश की, और यह वही परिणाम देता है, इसलिए इससे कोई फर्क नहीं पड़ता।

तो इस मामले में सी ++ नाम उलझन में "पूर्ववत" क्यों नहीं किया जाता है? क्या इसका जीसीसी का उपयोग करने के साथ कुछ लेना देना है, जिसका मतलब है कि मैं libstdC++ का उपयोग कर रहा हूं?

+1

मैं आर्क लिनक्स और 'परफ रिपोर्ट' का उपयोग कर रहा हूं सही प्रतीक demanging दिखाता है। Perf के लिए मैन पेज यह भी दिखाता है कि एक '- डीमंगल' विकल्प है जो डिफ़ॉल्ट रूप से सक्षम है। चूंकि मैं वही व्यवहार नहीं देख रहा हूं क्योंकि मेरे पास कोई जवाब नहीं है, लेकिन जो आप देख रहे हैं उसे डिफ़ॉल्ट व्यवहार की उम्मीद नहीं है। –

+0

मैंने मैन्युअल रूप से उस स्विच को जोड़ने का प्रयास किया, लेकिन यह कुछ भी नहीं बदला – adam10603

+0

@ गैब्रियलउथर्न क्या आप जीसीसी का भी उपयोग कर रहे हैं? – adam10603

उत्तर

1

जब perf report आप _Z*, _ZN*, _ZL* आदि की तरह घायल नाम देता है, तो इसका मतलब है कि आपके perf उपकरण demangling कार्य करने के लिए या वह अक्षम साथ उपयोग के बिना संकलित किया गया।

http://elixir.free-electrons.com/linux/v4.2.6/source/tools/perf/Makefile.perf

# Define NO_DEMANGLE if you do not want C++ symbol demangling. 
# Define NO_LIBELF if you do not want libelf dependency (e.g. cross-builds) 

http://elixir.free-electrons.com/linux/v4.2.6/source/tools/perf/config/Makefile

ifdef NO_LIBELF 
... 
    NO_DEMANGLE := 1 
... 
else 
    ifeq ($(feature-libelf), 0) 
    ifeq ($(feature-glibc), 1) 
     LIBC_SUPPORT := 1 
    endif 
    ... 
    ifeq ($(LIBC_SUPPORT),1) 
     ... 
     NO_DEMANGLE := 1 
    ... 

टेस्ट tools/build/feature निर्देशिका में हैं:: परीक्षण कार्यक्रम libelf की elf_begin फ़ंक्शन का उपयोग करता है, तो http://elixir.free-electrons.com/linux/v4.2.6/source/tools/build/feature और libelf सुविधा सक्षम है वहाँ Makefiles में demangler पता लगाने के लिए कोड है (<libelf.h> header of elfutils package, -lelf लिंकिंग) उपलब्ध है (और कुछ देता है? क्या परीक्षण चलाया जाता है? क्रॉस- बनाता है जब कर्नेल बिल्डर मशीन ./test-libelf.bin के साथ सीधे लक्ष्य मशीन एल्फ बाइनरी नहीं चला सकती है और वास्तविक मशीन या कुछ उपयोगकर्ता/सिस्टम qemu के लिए ssh का उपयोग करना चाहिए?)।

और पर्फ़ कार्यान्वयन में कोड demangling करने के लिए (का उपयोग कर cplus_demangle अगर HAVE_CPLUS_DEMANGLE_SUPPORT परिभाषित, कोई demangle का उपयोग कर NO_DEMANGLE Makefiles के बाद सेट कर दिया जाता है, bfd.h और bfd_demangle समारोह docs - 2.3.1.24 bfd_demangle उपयोग करते हुए): http://elixir.free-electrons.com/linux/v4.2.6/source/tools/perf/util/symbol-elf.c#L19

#ifdef HAVE_CPLUS_DEMANGLE_SUPPORT 
extern char *cplus_demangle(const char *, int); 

static inline char *bfd_demangle(void __maybe_unused *v, const char *c, int i) 
{ 
    return cplus_demangle(c, i); 
} 
#else 
#ifdef NO_DEMANGLE 
static inline char *bfd_demangle(void __maybe_unused *v, 
       const char __maybe_unused *c, 
       int __maybe_unused i) 
{ 
    return NULL; 
} 
#else 
#define PACKAGE 'perf' 
#include <bfd.h> 
#endif 

यह सब कुछ अजीब है (अभी भी सी ++ 11 युग पोस्ट में लिनक्स दुनिया में कोई मानक सी ++ डिमंगल फ़ंक्शन नहीं है?)। और आपके परफ को गलत समझा गया था या गलत कॉन्फ़िगर किया गया था - यही वजह है कि यह नामों को बदनाम नहीं करता है।बिलीव linked answerMichal Fapso द्वारा यह कहता है कि यह उबंटू - https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1396654 का 1396654 बग है।

आप c++filt कार्यक्रम के साथ पर्फ़ की छानने उत्पादन के हैक कर सकता है लेकिन यह पर्फ़ के इंटरैक्टिव डिफ़ॉल्ट TUI इंटरफ़ेस का उपयोग करने से रोकने के (less जोड़ सकते हैं या सामान्य PAGEDOWN साथ बहुत लंबे सूचियों को देख पाने पाठ फ़ाइलों को लिखने/PAGEUP):

perf report | c++filt | less 
perf annotate function_name | c++filt | less 
# or: perf annotate -s function_name | c++filt | less 

या आप अद्यतन कर सकते हैं/के रूप में his comment

4 में billyw ने सुझाव दिया अपने पर्फ़ पुन: संयोजित^ऐसा लगता है कि Ubuntu पर कर रहे हैं। मुझे संदेह है कि यह आपकी समस्या और समाधान है: https://stackoverflow.com/a/34061874/2166274 - बिलीव मार्च 3 '16 17:31

संबंधित मुद्दे