{"id":120,"date":"2004-05-12T11:02:53","date_gmt":"2004-05-12T11:02:53","guid":{"rendered":"http:\/\/www.lucas-nussbaum.net\/blog\/?p=120"},"modified":"2004-05-12T11:02:53","modified_gmt":"2004-05-12T11:02:53","slug":"graphes-dappel-en-c-et-c","status":"publish","type":"post","link":"https:\/\/www.lucas-nussbaum.net\/blog\/?p=120","title":{"rendered":"Graphes d&#8217;appel en C et C++"},"content":{"rendered":"<p>Je viens de d\u00e9couvrir quelque chose que je cherchais sans le savoir depuis longtemps : la possibilit\u00e9 de faire un graphe des appels de fonction dans un programme. C&#8217;est un <a href=\"http:\/\/linuxfr.org\/~cykl\/12505.html\">journal sur LinuxFR<\/a> qui m&#8217;a donn\u00e9 envie de me pencher sur le sujet. La conclusion du journal \u00e9tait que la solution la plus simple est de :<\/p>\n<ul>\n<li>&#8211; compiler le programme avec les options de profiling (-pg).<\/li>\n<li>&#8211; lancer le programme : .\/prog<\/li>\n<li>&#8211; r\u00e9cup\u00e9rer la sortie de gprof : gprof .\/prog &gt; fichier.out<\/li>\n<li>&#8211; la parser pour en g\u00e9n\u00e9rer un fichier .dot. cat fichier.out | <a href=\"http:\/\/mvertes.free.fr\/\">.\/cgprof<\/a> &gt; fichier2.out<\/li>\n<li>&#8211; avec graphviz, g\u00e9n\u00e9rer un graphique : dot -Tps fichier2.out -o prog.ps<\/li>\n<\/ul>\n<p>Ca marche sans probl\u00e8mes pour les programmes en C, mais c&#8217;est plus difficile avec les programmes en C++, car la sortie de gprof est un peu diff\u00e9rente (en C, les param\u00e8tres des fonctions ne sont pas affich\u00e9s, alors qu&#8217;en C++, oui). Je me suis attaqu\u00e9 au probl\u00e8me, et j&#8217;ai commenc\u00e9 \u00e0 r\u00e9\u00e9crire cgprof pour prendre en compte les param\u00e8tres. Mauvaise id\u00e9e, le code est assez immonde. Du coup, j&#8217;ai chang\u00e9 d&#8217;approche : j&#8217;ai demand\u00e9 \u00e0 gprof de ne pas <i>demangler<\/i> les noms de fonctions (option &#8211;no-demangle), j&#8217;ai g\u00e9n\u00e9r\u00e9 le .dot avec les noms de fonction <i>mangl\u00e9s<\/i>, et j&#8217;ai utilis\u00e9 c++filt (livr\u00e9 dans binutils) pour d\u00e9mangler directement le .dot. Et <a href=\"\/dotclear\/images\/pj.png\">ca marche<\/a> !<\/p>\n<p>Il peut aussi \u00eatre souhaitable de ne pas afficher les arguments des fonctions, histoire de gagner un peu de place. C&#8217;est facile : sed -i &#8216;s\/([^)])\/\/g&#8217; fichier2.out et hop !<\/p>\n<p>Ah j&#8217;oubliais : dans mon exemple, j&#8217;ai supprim\u00e9 les indications sur la couleur, car apparemment, la formule que cgprof utilise ne donne pas de supers r\u00e9sultats. Ca se fait avec un grep -v sur le .out.<\/p>\n<p>Autres am\u00e9liorations possibles, cette fois au niveau de gprof :<\/p>\n<ul>\n<li>L&#8217;option &#8211;static-call-graph demande \u00e0 gprof de faire une analyse statique du code pour d\u00e9terminer le graphe d&#8217;appels.<\/li>\n<li>Les options -q et -Q permettent de contr\u00f4ler plus finement le graphe d&#8217;appels. -q permet de d\u00e9finir la racine de l&#8217;arbre (pour ne grapher q&#8217;un sous-arbre), alors que -Q permet d&#8217;exclure un sous-arbre.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Je viens de d\u00e9couvrir quelque chose que je cherchais sans le savoir depuis longtemps : la possibilit\u00e9 de faire un graphe des appels de fonction dans un programme. C&#8217;est un journal sur LinuxFR qui m&#8217;a donn\u00e9 envie de me pencher sur le sujet. La conclusion du journal \u00e9tait que la solution la plus simple est [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"0","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-120","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/120","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=120"}],"version-history":[{"count":0,"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=\/wp\/v2\/posts\/120\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=120"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=120"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.lucas-nussbaum.net\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=120"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}