[nemiver/profiler] WIP
- From: Fabien Parent <fparent src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nemiver/profiler] WIP
- Date: Sun, 5 Aug 2012 16:27:34 +0000 (UTC)
commit 72253afcbe0a8212454051613ad70b67d5d5ffd1
Author: Fabien Parent <parent f gmail com>
Date: Sun Jul 22 21:47:46 2012 +0200
WIP
src/profengine/Makefile.am | 1 +
src/profengine/nmv-perf-engine.cc | 66 ++++++++++++++++++++-
src/profengine/nmv-perf-server.cc | 117 ++++++++++++++++++++++++++++++++----
3 files changed, 169 insertions(+), 15 deletions(-)
---
diff --git a/src/profengine/Makefile.am b/src/profengine/Makefile.am
index e054917..6385e74 100644
--- a/src/profengine/Makefile.am
+++ b/src/profengine/Makefile.am
@@ -28,6 +28,7 @@ publicheadersdir=$(NEMIVER_INCLUDE_DIR)/dynmods
libperfmod_la_LDFLAGS=-module -avoid-version -Wl,--as-needed
libperfmod_la_LIBADD=libperfengine.la @NEMIVERCOMMON_LIBS@ \
+ NEMIVERPROFPERSP_LIBS@ \
$(abs_top_builddir)/src/common/libnemivercommon.la
diff --git a/src/profengine/nmv-perf-engine.cc b/src/profengine/nmv-perf-engine.cc
index a629757..030f82c 100644
--- a/src/profengine/nmv-perf-engine.cc
+++ b/src/profengine/nmv-perf-engine.cc
@@ -34,6 +34,8 @@
#include <sys/types.h>
#include <signal.h>
#include <cstdio>
+#include <giomm.h>
+#include <glibmm.h>
NEMIVER_BEGIN_NAMESPACE (nemiver)
@@ -62,6 +64,9 @@ struct PerfEngine::Priv {
sigc::signal<void, const UString&> record_done_signal;
sigc::signal<void, const UString&, const UString&> symbol_annotated_signal;
+ Glib::RefPtr<Gio::DBus::Connection> server_connection;
+ Glib::RefPtr<Gio::DBus::Proxy> proxy;
+
Priv () :
conf_manager (0),
perf_pid (0),
@@ -69,8 +74,25 @@ struct PerfEngine::Priv {
perf_stdout_fd (0),
perf_stderr_fd (0),
perf_stdout_channel (0),
- call_graph (0)
+ call_graph (0),
+ server_connection (0),
+ proxy (0)
+ {
+ init ();
+ }
+
+ void
+ init ()
{
+ server_connection =
+ Gio::DBus::Connection::get_sync (Gio::DBus::BUS_TYPE_SESSION);
+ THROW_IF_FAIL (server_connection);
+
+ proxy = Gio::DBus::Proxy::create_sync (server_connection,
+ "org.gnome.nemiver.profiler",
+ "/org/gnome/nemiver/profiler",
+ "org.gnome.nemiver.profiler");
+ THROW_IF_FAIL (proxy);
}
IConfMgr&
@@ -318,6 +340,22 @@ struct PerfEngine::Priv {
return false;
}
+ void
+ on_detached_from_process (Glib::RefPtr<Gio::AsyncResult> &a_result)
+ {
+ NEMIVER_TRY;
+
+ THROW_IF_FAIL (proxy);
+ Glib::VariantContainerBase result = proxy->call_finish (a_result);
+
+ Glib::Variant<Glib::ustring> record;
+ result.get_child (record);
+
+ record_done_signal.emit (record.get ());
+
+ NEMIVER_CATCH_NOX;
+ }
+
~Priv ()
{
LOG_D ("delete", "destructor-domain");
@@ -345,11 +383,33 @@ PerfEngine::do_init (IConfMgrSafePtr a_conf_mgr)
void
PerfEngine::attach_to_pid (int a_pid)
{
- std::vector<UString> argv;
+ THROW_IF_FAIL (m_priv);
+ THROW_IF_FAIL (m_priv->proxy);
+
+ std::vector<Glib::ustring> options;
+
+ Glib::Variant<int> pid_param = Glib::Variant<int>::create (a_pid);
+ Glib::Variant<std::vector<Glib::ustring> > options_param =
+ Glib::Variant<std::vector<Glib::ustring> >::create (options);
+
+ std::vector<Glib::VariantBase> parameters;
+ parameters.push_back (pid_param);
+ parameters.push_back (options_param);
+
+ Glib::VariantContainerBase parameters_variant =
+ Glib::VariantContainerBase::create_tuple (parameters);
+
+ m_priv->proxy->call
+ ("AttachToPID",
+ sigc::mem_fun (*m_priv, &PerfEngine::Priv::on_detached_from_process),
+ parameters_variant);
+
+/* std::vector<UString> argv;
argv.push_back ("--pid");
argv.push_back (UString::compose ("%1", a_pid));
record (argv);
+*/
}
void
@@ -470,6 +530,8 @@ PerfEngine::stop_recording ()
void
PerfEngine::report (const UString &a_data_file)
{
+ THROW_IF_FAIL (Glib::file_test (a_data_file, Glib::FILE_TEST_EXISTS));
+
std::vector<UString> argv;
argv.push_back ("perf");
argv.push_back ("report");
diff --git a/src/profengine/nmv-perf-server.cc b/src/profengine/nmv-perf-server.cc
index 9325ffd..68baf5c 100644
--- a/src/profengine/nmv-perf-server.cc
+++ b/src/profengine/nmv-perf-server.cc
@@ -26,24 +26,31 @@
#include "common/nmv-namespace.h"
#include "common/nmv-safe-ptr.h"
#include "common/nmv-exception.h"
+#include "common/nmv-ustring.h"
+#include "common/nmv-proc-utils.h"
#include <glibmm.h>
#include <giomm.h>
#include <glib/gi18n.h>
-
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdio.h>
#include <iostream>
using nemiver::common::SafePtr;
+using nemiver::common::FreeUnref;
+using nemiver::common::DefaultRef;
+using nemiver::common::UString;
NEMIVER_BEGIN_NAMESPACE (nemiver)
static const char *const NMV_BUS_NAME = "org.gnome.nemiver.profiler";
static const char *const NMV_DBUS_PROFILER_SERVER_INTROSPECTION_DATA =
"<node>"
- " <interface name='org.gnome.nemiver.profilers'>"
+ " <interface name='org.gnome.nemiver.profiler'>"
" <method name='AttachToPID'>"
" <arg type='i' name='pid' direction='in' />"
- " <arg type='u' name='cookie' direction='in' />"
+// " <arg type='u' name='cookie' direction='in' />"
" <arg type='as' name='arguments' direction='in' />"
" <arg type='s' name='data_filepath' direction='out' />"
" </method>"
@@ -71,17 +78,56 @@ struct PerfServer::Priv {
Glib::RefPtr<Gio::DBus::NodeInfo> introspection_data;
Gio::DBus::InterfaceVTable interface_vtable;
+ int perf_pid;
+ int master_pty_fd;
+ int perf_stdout_fd;
+ int perf_stderr_fd;
+
Priv () :
// subject (polkit_system_bus_name_new ("org.gnome.nemiver")),
bus_id (0),
registration_id (0),
introspection_data (0),
interface_vtable
- (sigc::mem_fun (*this, &PerfServer::Priv::on_new_request))
+ (sigc::mem_fun (*this, &PerfServer::Priv::on_new_request)),
+ perf_pid (0),
+ master_pty_fd (0),
+ perf_stdout_fd (0),
+ perf_stderr_fd (0)
{
init ();
}
+ bool
+ on_wait_for_record_to_exit (const Glib::RefPtr<Gio::DBus::MethodInvocation>
+ &a_invocation,
+ Glib::ustring a_report_filepath)
+ {
+ int status = 0;
+ pid_t pid = waitpid (perf_pid, &status, WNOHANG);
+ bool is_terminated = WIFEXITED (status) || WIFSIGNALED (status);
+
+ if (pid == perf_pid && is_terminated) {
+ g_spawn_close_pid (perf_pid);
+ perf_pid = 0;
+ master_pty_fd = 0;
+ perf_stdout_fd = 0;
+ perf_stderr_fd = 0;
+
+ Glib::Variant<Glib::ustring> perf_data =
+ Glib::Variant<Glib::ustring>::create (a_report_filepath);
+
+ Glib::VariantContainerBase response =
+ Glib::VariantContainerBase::create_tuple (perf_data);
+
+ a_invocation->return_value (response);
+
+ return false;
+ }
+
+ return true;
+ }
+
void
on_new_request (const Glib::RefPtr<Gio::DBus::Connection>&,
const Glib::ustring&,
@@ -96,12 +142,57 @@ struct PerfServer::Priv {
THROW_IF_FAIL (a_invocation);
- if(a_request_name == "AttachToPID")
- {
+ if(a_request_name == "AttachToPID") {
Glib::Variant<int> pid_param;
+ Glib::Variant<std::vector<Glib::ustring> > options_param;
a_parameters.get_child (pid_param);
-
- std::cout << "PID: " << pid_param.get () << std::endl;
+ a_parameters.get_child (options_param, 1);
+
+ int pid = pid_param.get ();
+ std::vector<Glib::ustring> options (options_param.get ());
+ for (std::vector<Glib::ustring>::iterator iter = options.begin ();
+ iter != options.end ();
+ ++iter) {
+ if (*iter != "--output") {
+ continue;
+ }
+
+ Gio::DBus::Error error
+ (Gio::DBus::Error::INVALID_ARGS,
+ _("--output parameter is "
+ "forbidden for security reasons"));
+ a_invocation->return_error (error);
+ }
+
+ SafePtr<char, DefaultRef, FreeUnref> filepath (tempnam(0, 0));
+ THROW_IF_FAIL (filepath);
+
+ std::vector<UString> argv;
+ argv.push_back ("perf");
+ argv.push_back ("record");
+ argv.push_back ("--pid");
+ argv.push_back (UString::compose ("%1", pid));
+ argv.push_back ("--output");
+ argv.push_back (filepath.get ());
+ argv.insert (argv.end (), options.begin (), options.end ());
+
+ bool is_launched =
+ common::launch_program (argv,
+ perf_pid,
+ master_pty_fd,
+ perf_stdout_fd,
+ perf_stderr_fd);
+
+ THROW_IF_FAIL (is_launched);
+
+ Glib::RefPtr<Glib::MainContext> context =
+ Glib::MainContext::get_default ();
+ context->signal_idle ().connect
+ (sigc::bind<const Glib::RefPtr<Gio::DBus::MethodInvocation>, Glib::ustring>
+ (sigc::mem_fun (*this,
+ &PerfServer::Priv::on_wait_for_record_to_exit),
+ a_invocation,
+ filepath.get ()));
}
else
{
@@ -122,13 +213,13 @@ struct PerfServer::Priv {
bus_id = Gio::DBus::own_name
(Gio::DBus::BUS_TYPE_SESSION,
NMV_BUS_NAME,
- sigc::mem_fun(*this, &PerfServer::Priv::on_bus_acquired),
- sigc::mem_fun(*this, &PerfServer::Priv::on_name_acquired),
- sigc::mem_fun(*this, &PerfServer::Priv::on_name_lost));
+ sigc::mem_fun (*this, &PerfServer::Priv::on_bus_acquired),
+ sigc::mem_fun (*this, &PerfServer::Priv::on_name_acquired),
+ sigc::mem_fun (*this, &PerfServer::Priv::on_name_lost));
}
void
- on_bus_acquired(const Glib::RefPtr<Gio::DBus::Connection> &a_connection,
+ on_bus_acquired (const Glib::RefPtr<Gio::DBus::Connection> &a_connection,
const Glib::ustring&)
{
NEMIVER_TRY;
@@ -136,7 +227,7 @@ struct PerfServer::Priv {
THROW_IF_FAIL (a_connection);
registration_id = a_connection->register_object
("/org/gnome/nemiver/profiler",
- introspection_data->lookup_interface(),
+ introspection_data->lookup_interface (),
interface_vtable);
NEMIVER_CATCH_NOX;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]