[nemiver/profiler: 11/11] Basic support of symbol annotation



commit f4e61e8469e776eeba3b19613bdd8918ee9b018d
Author: Fabien Parent <parent f gmail com>
Date:   Sun Jun 17 16:06:22 2012 +0200

    Basic support of symbol annotation

 src/persp/profperspective/nmv-call-list.cc        |   33 ++-
 src/persp/profperspective/nmv-call-list.h         |    4 +-
 src/persp/profperspective/nmv-prof-perspective.cc |   49 +++-
 src/persp/profperspective/nmv-prof-perspective.h  |    2 +
 src/persp/profperspective/ui/runprogramdialog.ui  |  329 ---------------------
 src/profengine/nmv-i-profiler.h                   |    5 +
 src/profengine/nmv-perf-engine.cc                 |  101 +++++++-
 src/profengine/nmv-perf-engine.h                  |    4 +
 src/uicommon/nmv-source-editor.cc                 |    4 +-
 9 files changed, 187 insertions(+), 344 deletions(-)
---
diff --git a/src/persp/profperspective/nmv-call-list.cc b/src/persp/profperspective/nmv-call-list.cc
index 4ceab34..238ffe6 100644
--- a/src/persp/profperspective/nmv-call-list.cc
+++ b/src/persp/profperspective/nmv-call-list.cc
@@ -57,10 +57,10 @@ struct CallList::Priv {
     Gtk::ScrolledWindow body;
     CallListColumns columns;
     Glib::RefPtr<Gtk::TreeStore> store;
-    IProfilerSafePtr profiler;
+    IProfPerspective &perspective;
 
-    Priv (const IProfilerSafePtr &a_profiler) :
-        profiler (a_profiler)
+    Priv (IProfPerspective &a_perspective) :
+        perspective (a_perspective)
     {
         body.add (treeview);
         body.set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
@@ -77,6 +77,8 @@ struct CallList::Priv {
         treeview.append_column (_("Shared Object"), columns.dso);
         int usage_col_id = treeview.append_column (_("Overhead"), *renderer);
         treeview.set_model (store);
+        treeview.signal_row_activated ().connect
+            (sigc::mem_fun (*this, &CallList::Priv::on_signal_row_activated));
 
         Gtk::TreeViewColumn *column = treeview.get_column (usage_col_id - 1);
         if (column) {
@@ -86,6 +88,27 @@ struct CallList::Priv {
     }
 
     void
+    on_signal_row_activated (const Gtk::TreeModel::Path &a_path,
+                             Gtk::TreeViewColumn*)
+    {
+        NEMIVER_TRY
+
+        THROW_IF_FAIL (store);
+
+        Gtk::TreeModel::iterator iter = store->get_iter (a_path);
+        if (!iter) {
+            return;
+        }
+
+        CallGraphNodeSafePtr node = iter->get_value (columns.call_node);
+        THROW_IF_FAIL (node);
+
+        perspective.annotate_symbol (node->symbol ());
+
+        NEMIVER_CATCH
+    }
+
+    void
     add_node (CallGraphNodeSafePtr a_call_graph_node,
               Gtk::TreeModel::iterator a_parent = Gtk::TreeModel::iterator ())
     {
@@ -129,8 +152,8 @@ CallList::load_call_graph (CallGraphSafePtr a_call_graph)
     m_priv->add_node(a_call_graph);
 }
 
-CallList::CallList (const IProfilerSafePtr &a_profiler) :
-    m_priv (new Priv (a_profiler))
+CallList::CallList (IProfPerspective &a_perspective) :
+    m_priv (new Priv (a_perspective))
 {
 }
 
diff --git a/src/persp/profperspective/nmv-call-list.h b/src/persp/profperspective/nmv-call-list.h
index 662fac0..74b47eb 100644
--- a/src/persp/profperspective/nmv-call-list.h
+++ b/src/persp/profperspective/nmv-call-list.h
@@ -28,7 +28,7 @@
 #include "common/nmv-safe-ptr.h"
 #include "common/nmv-namespace.h"
 #include "nmv-call-graph-node.h"
-#include "nmv-i-profiler.h"
+#include "nmv-prof-perspective.h"
 
 namespace Gtk {
     class Widget;
@@ -47,7 +47,7 @@ class CallList {
     SafePtr<Priv> m_priv;
 public:
 
-    CallList (const IProfilerSafePtr&);
+    CallList (IProfPerspective&);
     ~CallList ();
     Gtk::Widget& widget () const;
     void load_call_graph (CallGraphSafePtr);
diff --git a/src/persp/profperspective/nmv-prof-perspective.cc b/src/persp/profperspective/nmv-prof-perspective.cc
index b83950c..094a3eb 100644
--- a/src/persp/profperspective/nmv-prof-perspective.cc
+++ b/src/persp/profperspective/nmv-prof-perspective.cc
@@ -29,8 +29,10 @@
 #include "nmv-call-list.h"
 #include "nmv-spinner-tool-item.h"
 #include "nmv-record-dialog.h"
+#include "nmv-i-profiler.h"
 #include "common/nmv-safe-ptr-utils.h"
 #include "common/nmv-str-utils.h"
+#include "uicommon/nmv-source-editor.h"
 
 #include <list>
 #include <glib/gi18n.h>
@@ -68,7 +70,7 @@ class ProfPerspective : public IProfPerspective {
     SafePtr<Gtk::Toolbar> toolbar;
 
     Glib::RefPtr<Gtk::ActionGroup> default_action_group;
-    Gtk::HPaned body;
+    Gtk::Notebook body;
     IWorkbench *workbench;
     GOptionGroup *opt_group;
 
@@ -105,11 +107,14 @@ public:
                          bool a_scale_counter_values,
                          bool a_do_callgraph,
                          bool a_child_inherit_counters);
+    void annotate_symbol (const UString &a_symbol_name);
 
     void on_run_executable_action ();
     void on_load_report_file_action ();
     void on_report_done_signal (CallGraphSafePtr a_call_graph);
     void on_record_done_signal (const UString &a_report_file);
+    void on_symbol_annotated_signal (const UString &a_symbol_name,
+                                     const UString &a_annotation);
 
     IProfilerSafePtr& profiler ();
 
@@ -265,24 +270,48 @@ ProfPerspective::init_signals ()
 
     profiler ()->record_done_signal ().connect (sigc::mem_fun
         (*this, &ProfPerspective::on_record_done_signal));
+
+    profiler ()->symbol_annotated_signal ().connect (sigc::mem_fun
+        (*this, &ProfPerspective::on_symbol_annotated_signal));
 }
 
 void
 ProfPerspective::init_body ()
 {
+    call_list.reset (new CallList (*this));
+    call_list->widget ().show ();
+    body.append_page (call_list->widget (), _("Report"));
     body.show_all ();
 }
 
 void
+ProfPerspective::on_symbol_annotated_signal (const UString &a_symbol_name,
+                                             const UString &a_annotation)
+{
+    NEMIVER_TRY
+
+    Glib::RefPtr<Gsv::Buffer> buffer = SourceEditor::create_source_buffer ();
+    THROW_IF_FAIL (buffer);
+    buffer->set_text (a_annotation);
+
+    SourceEditor *editor = new SourceEditor (".", buffer);
+    THROW_IF_FAIL (editor);
+    int page = body.append_page (*Gtk::manage (editor), a_symbol_name);
+    body.set_current_page (page);
+    body.show_all ();
+
+    THROW_IF_FAIL (throbber);
+    throbber->stop ();
+
+    NEMIVER_CATCH
+}
+
+void
 ProfPerspective::on_report_done_signal (CallGraphSafePtr a_call_graph)
 {
     NEMIVER_TRY
 
-    call_list.reset (new CallList (profiler ()));
     call_list->load_call_graph (a_call_graph);
-    call_list->widget ().show ();
-    body.pack1 (call_list->widget ());
-    body.show_all ();
 
     THROW_IF_FAIL (throbber);
     throbber->stop ();
@@ -424,6 +453,16 @@ ProfPerspective::load_report_file ()
 }
 
 void
+ProfPerspective::annotate_symbol (const UString &a_symbol_name)
+{
+    THROW_IF_FAIL (profiler ());
+    profiler ()->annotate_symbol (a_symbol_name);
+
+    THROW_IF_FAIL (throbber);
+    throbber->start ();
+}
+
+void
 ProfPerspective::on_load_report_file_action ()
 {
     NEMIVER_TRY
diff --git a/src/persp/profperspective/nmv-prof-perspective.h b/src/persp/profperspective/nmv-prof-perspective.h
index 75731b9..f91792c 100644
--- a/src/persp/profperspective/nmv-prof-perspective.h
+++ b/src/persp/profperspective/nmv-prof-perspective.h
@@ -41,6 +41,8 @@ public:
     {
     }
 
+    virtual void annotate_symbol (const UString &a_symbol_name) = 0;
+
     virtual ~IProfPerspective () {};
 };//end class IProfPerspective
 
diff --git a/src/profengine/nmv-i-profiler.h b/src/profengine/nmv-i-profiler.h
index 74842e5..d8277ed 100644
--- a/src/profengine/nmv-i-profiler.h
+++ b/src/profengine/nmv-i-profiler.h
@@ -69,6 +69,9 @@ public:
         report_done_signal () const = 0;
 
     virtual sigc::signal<void, const UString&> record_done_signal () const = 0;
+
+    virtual sigc::signal<void, const UString&, const UString&>
+        symbol_annotated_signal () const = 0;
     /// @}
 
     virtual void report (const UString &a_data_file) = 0;
@@ -79,6 +82,8 @@ public:
                          bool a_do_callgraph,
                          bool a_child_inherit_counters) = 0;
 
+    virtual void annotate_symbol (const UString &a_symbol_name) = 0;
+
 //    virtual void attach_to_pid () = 0;
 
 
diff --git a/src/profengine/nmv-perf-engine.cc b/src/profengine/nmv-perf-engine.cc
index a157e51..6fa9969 100644
--- a/src/profengine/nmv-perf-engine.cc
+++ b/src/profengine/nmv-perf-engine.cc
@@ -34,6 +34,7 @@
 
 NEMIVER_BEGIN_NAMESPACE (nemiver)
 
+const char *const PERF_ANNOTATE_PARSING_DOMAIN = "perf-annotate-parsing-domain";
 const char *const PERF_REPORT_PARSING_DOMAIN = "perf-report-parsing-domain";
 
 using common::DynModIfaceSafePtr;
@@ -50,9 +51,12 @@ struct PerfEngine::Priv {
 
     std::stack<CallGraphNodeSafePtr> call_stack;
     CallGraphSafePtr call_graph;
+    UString annotation_buffer;
+    UString annotated_symbol;
 
     sigc::signal<void, CallGraphSafePtr> report_done_signal;
     sigc::signal<void, const UString&> record_done_signal;
+    sigc::signal<void, const UString&, const UString&> symbol_annotated_signal;
 
     Priv () :
         perf_pid (0),
@@ -89,6 +93,34 @@ struct PerfEngine::Priv {
     }
 
     bool
+    on_wait_for_symbol_annotation_to_exit ()
+    {
+        NEMIVER_TRY
+
+        THROW_IF_FAIL (perf_stdout_channel);
+
+        int status = 0;
+        pid_t pid = waitpid (perf_pid, &status, WNOHANG);
+        if (pid == perf_pid && WIFEXITED (status)) {
+            perf_stdout_channel->close ();
+            perf_stdout_channel.reset ();
+            g_spawn_close_pid (perf_pid);
+            perf_pid = 0;
+            master_pty_fd = 0;
+            perf_stdout_fd = 0;
+            perf_stderr_fd = 0;
+
+            symbol_annotated_signal.emit (annotated_symbol, annotation_buffer);
+
+            return false;
+        }
+
+        NEMIVER_CATCH_NOX
+
+        return true;
+    }
+
+    bool
     on_wait_for_report_to_exit ()
     {
         NEMIVER_TRY
@@ -212,6 +244,27 @@ struct PerfEngine::Priv {
     }
 
     bool
+    read_symbol_annotation (Glib::IOCondition)
+    {
+        NEMIVER_TRY
+
+        THROW_IF_FAIL (perf_stdout_channel);
+
+        UString line;
+        Glib::IOStatus status;
+
+        do {
+            status = perf_stdout_channel->read_line (line);
+            LOG_D (line, PERF_ANNOTATE_PARSING_DOMAIN);
+            annotation_buffer += line;
+        } while (status == Glib::IO_STATUS_NORMAL);
+
+        NEMIVER_CATCH_NOX
+
+        return false;
+    }
+
+    bool
     read_report (Glib::IOCondition)
     {
         NEMIVER_TRY
@@ -279,8 +332,8 @@ PerfEngine::record (const UString &a_program_path,
     }
 
     argv.push_back ("--output");
-    argv.push_back ("--");
     argv.push_back (m_priv->record_filepath);
+    argv.push_back ("--");
     argv.push_back (a_program_path);
     argv.insert (argv.end (), a_argv.begin (), a_argv.end ());
 
@@ -307,6 +360,8 @@ PerfEngine::report (const UString &a_data_file)
     argv.push_back (a_data_file);
 
     THROW_IF_FAIL (m_priv);
+    m_priv->record_filepath = a_data_file;
+
     bool is_launched = common::launch_program (argv,
                                                m_priv->perf_pid,
                                                m_priv->master_pty_fd,
@@ -330,6 +385,43 @@ PerfEngine::report (const UString &a_data_file)
         (m_priv.get (), &PerfEngine::Priv::on_wait_for_report_to_exit));
 }
 
+void
+PerfEngine::annotate_symbol (const UString &a_symbol_name)
+{
+    THROW_IF_FAIL (m_priv);
+    m_priv->annotation_buffer.clear ();
+    m_priv->annotated_symbol = a_symbol_name;
+
+    std::vector<UString> argv;
+    argv.push_back ("perf");
+    argv.push_back ("annotate");
+    argv.push_back ("--stdio");
+    argv.push_back ("-i");
+    argv.push_back (m_priv->record_filepath);
+    argv.push_back (a_symbol_name);
+
+    bool is_launched = common::launch_program (argv,
+                                               m_priv->perf_pid,
+                                               m_priv->master_pty_fd,
+                                               m_priv->perf_stdout_fd,
+                                               m_priv->perf_stderr_fd);
+    THROW_IF_FAIL (is_launched);
+
+    m_priv->perf_stdout_channel =
+        Glib::IOChannel::create_from_fd (m_priv->perf_stdout_fd);
+
+    Glib::RefPtr<Glib::IOSource> io_source =
+        m_priv->perf_stdout_channel->create_watch (Glib::IO_IN);
+    io_source->connect (sigc::mem_fun
+        (m_priv.get (), &PerfEngine::Priv::read_symbol_annotation));
+    io_source->attach ();
+
+    Glib::RefPtr<Glib::MainContext> context = Glib::MainContext::get_default ();
+    context->signal_idle ().connect (sigc::mem_fun
+        (m_priv.get (),
+         &PerfEngine::Priv::on_wait_for_symbol_annotation_to_exit));
+}
+
 sigc::signal<void, CallGraphSafePtr>
 PerfEngine::report_done_signal () const
 {
@@ -344,6 +436,13 @@ PerfEngine::record_done_signal () const
     return m_priv->record_done_signal;
 }
 
+sigc::signal<void, const UString&, const UString&>
+PerfEngine::symbol_annotated_signal () const
+{
+    THROW_IF_FAIL (m_priv);
+    return m_priv->symbol_annotated_signal;
+}
+
 //****************************
 //</GDBEngine methods>
 //****************************
diff --git a/src/profengine/nmv-perf-engine.h b/src/profengine/nmv-perf-engine.h
index 9b00ea9..dfdd966 100644
--- a/src/profengine/nmv-perf-engine.h
+++ b/src/profengine/nmv-perf-engine.h
@@ -50,9 +50,13 @@ public:
                  bool a_do_callgraph,
                  bool a_child_inherit_counters);
 
+    void annotate_symbol (const UString &a_symbol_name);
+
     sigc::signal<void, CallGraphSafePtr> report_done_signal () const;
     sigc::signal<void> program_exited_signal () const;
     sigc::signal<void, const UString&> record_done_signal () const;
+    sigc::signal<void, const UString&, const UString&>
+        symbol_annotated_signal () const;
 }; // end namespace PerfEngine
 
 NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/uicommon/nmv-source-editor.cc b/src/uicommon/nmv-source-editor.cc
index 9dacbe5..b1a521e 100644
--- a/src/uicommon/nmv-source-editor.cc
+++ b/src/uicommon/nmv-source-editor.cc
@@ -646,7 +646,7 @@ struct SourceEditor::Priv {
         string path;
         if (!get_absolute_resource_path (a_image,
                                          path)) {
-            THROW ("could not get path to " + a_image);
+            return; //THROW ("could not get path to " + a_image);
         }
 
         Glib::RefPtr<Gsv::MarkAttributes> attributes = Gsv::MarkAttributes::create ();
@@ -735,7 +735,7 @@ SourceEditor::init ()
     //****************************
     string path = "";
     if (!m_priv->get_absolute_resource_path ("icons/line-pointer.png", path)) {
-        THROW ("could not get path to line-pointer.png");
+        return; //THROW ("could not get path to line-pointer.png");
     }
     Glib::RefPtr<Gsv::MarkAttributes> attributes = Gsv::MarkAttributes::create ();
     attributes->set_icon (Gio::Icon::create (path));



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