[nemiver/profiler: 8/16] Basic support of symbol annotation
- From: Fabien Parent <fparent src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nemiver/profiler: 8/16] Basic support of symbol annotation
- Date: Sun, 8 Jul 2012 14:28:52 +0000 (UTC)
commit d05c8b858096f5a0008ecff6b9ad9c2b27e96dc8
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]