[nemiver/profiler] Basic support of profiling running processes
- From: Fabien Parent <fparent src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nemiver/profiler] Basic support of profiling running processes
- Date: Sun, 5 Aug 2012 16:27:39 +0000 (UTC)
commit a758ea69e8d907e97073c58e49f16e9875079549
Author: Fabien Parent <parent f gmail com>
Date: Sat Jul 28 22:25:38 2012 +0200
Basic support of profiling running processes
configure.ac | 5 ++-
src/persp/profperspective/nmv-prof-perspective.cc | 3 +
src/profengine/Makefile.am | 8 ++--
src/profengine/nmv-perf-engine.cc | 22 ++++++++--
src/profengine/nmv-perf-server.cc | 47 +++++++++++++++++---
src/profengine/org.gnome.nemiver.profiler.conf.in | 14 ++++++
.../org.gnome.nemiver.profiler.service.in | 4 ++
7 files changed, 87 insertions(+), 16 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 939edad..32c9df0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -410,11 +410,12 @@ if test x$exec_prefix = xNONE ; then
exec_prefix=$prefix ;
fi
NEMIVER_LIBDIR=`eval echo $libdir`
+NEMIVER_BINDIR=`eval echo $bindir`
AC_SUBST(NEMIVER_INCLUDE_DIR)
AC_SUBST(NEMIVER_LIB_DIR_NAME)
AC_SUBST(NEMIVER_LIBDIR)
-
+AC_SUBST(NEMIVER_BINDIR)
if test x$ENABLE_GCC_SYMBOLS_VISIBILITY = xyes && test x$host_cpu != xx86_64 ; then
AC_DEFINE(HAS_GCC_VISIBILITY_SUPPORT,1,[gcc visibility support])
@@ -484,6 +485,8 @@ src/Makefile
src/dbgengine/varlistwalker.conf
src/profengine/Makefile
src/profengine/perfengine.conf
+ src/profengine/org.gnome.nemiver.profiler.service
+ src/profengine/org.gnome.nemiver.profiler.conf
src/confmgr/Makefile
src/confmgr/gconfmgr.conf
src/confmgr/gsettingsmgr.conf
diff --git a/src/persp/profperspective/nmv-prof-perspective.cc b/src/persp/profperspective/nmv-prof-perspective.cc
index 1b70185..f9c9f33 100644
--- a/src/persp/profperspective/nmv-prof-perspective.cc
+++ b/src/persp/profperspective/nmv-prof-perspective.cc
@@ -631,6 +631,9 @@ ProfPerspective::attach_to_process (unsigned a_pid)
THROW_IF_FAIL (throbber);
throbber->start ();
+
+ THROW_IF_FAIL (recording_action_group);
+ recording_action_group->set_sensitive (true);
}
void
diff --git a/src/profengine/Makefile.am b/src/profengine/Makefile.am
index 6385e74..9408476 100644
--- a/src/profengine/Makefile.am
+++ b/src/profengine/Makefile.am
@@ -41,11 +41,11 @@ nmvperfserver= NEMIVER_MODULES_DIR@
nmvperfserver_LDADD= NEMIVERPROFPERSP_LIBS@ \
$(abs_top_builddir)/src/common/libnemivercommon.la
-#service_DATA=org.gnome.nemiver.profiler.service.in
-#servicedir=
+service_DATA=org.gnome.nemiver.profiler.service
+servicedir=$(datadir)/dbus-1/system-services
-#policy_DATA=org.gnome.nemiver.profiler.policy.in
-#policydir=
+bus_DATA=org.gnome.nemiver.profiler.conf.in
+busdir=/etc/dbus-1/system.d/
INCLUDES= NEMIVERCOMMON_CFLAGS@ @NEMIVERPROFPERSP_CFLAGS@ \
-DENABLE_NLS=1 -DDATADIR=\"${datadir}\" \
diff --git a/src/profengine/nmv-perf-engine.cc b/src/profengine/nmv-perf-engine.cc
index 030f82c..df2bc07 100644
--- a/src/profengine/nmv-perf-engine.cc
+++ b/src/profengine/nmv-perf-engine.cc
@@ -64,6 +64,7 @@ struct PerfEngine::Priv {
sigc::signal<void, const UString&> record_done_signal;
sigc::signal<void, const UString&, const UString&> symbol_annotated_signal;
+ bool is_using_prof_server;
Glib::RefPtr<Gio::DBus::Connection> server_connection;
Glib::RefPtr<Gio::DBus::Proxy> proxy;
@@ -75,6 +76,7 @@ struct PerfEngine::Priv {
perf_stderr_fd (0),
perf_stdout_channel (0),
call_graph (0),
+ is_using_prof_server (false),
server_connection (0),
proxy (0)
{
@@ -85,7 +87,7 @@ struct PerfEngine::Priv {
init ()
{
server_connection =
- Gio::DBus::Connection::get_sync (Gio::DBus::BUS_TYPE_SESSION);
+ Gio::DBus::Connection::get_sync (Gio::DBus::BUS_TYPE_SYSTEM);
THROW_IF_FAIL (server_connection);
proxy = Gio::DBus::Proxy::create_sync (server_connection,
@@ -389,16 +391,21 @@ PerfEngine::attach_to_pid (int a_pid)
std::vector<Glib::ustring> options;
Glib::Variant<int> pid_param = Glib::Variant<int>::create (a_pid);
+ Glib::Variant<int> uid_param = Glib::Variant<int>::create (getuid ());
+ Glib::Variant<int> gid_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 (uid_param);
+ parameters.push_back (gid_param);
parameters.push_back (options_param);
Glib::VariantContainerBase parameters_variant =
Glib::VariantContainerBase::create_tuple (parameters);
+ m_priv->is_using_prof_server = true;
m_priv->proxy->call
("AttachToPID",
sigc::mem_fun (*m_priv, &PerfEngine::Priv::on_detached_from_process),
@@ -495,6 +502,7 @@ PerfEngine::record (const std::vector<UString> &a_argv)
argv.push_back (m_priv->record_filepath);
argv.insert (argv.end (), a_argv.begin (), a_argv.end ());
+ m_priv->is_using_prof_server = false;
bool is_launched = common::launch_program (argv,
m_priv->perf_pid,
m_priv->master_pty_fd,
@@ -523,8 +531,13 @@ void
PerfEngine::stop_recording ()
{
THROW_IF_FAIL (m_priv);
- THROW_IF_FAIL (m_priv->perf_pid);
- kill(m_priv->perf_pid, SIGINT);
+
+ if (m_priv->is_using_prof_server) {
+ m_priv->proxy->call_sync ("DetachFromProcess");
+ } else {
+ THROW_IF_FAIL (m_priv->perf_pid);
+ kill (m_priv->perf_pid, SIGINT);
+ }
}
void
@@ -541,7 +554,7 @@ PerfEngine::report (const UString &a_data_file)
THROW_IF_FAIL (m_priv);
m_priv->record_filepath = a_data_file;
-
+ m_priv->is_using_prof_server = false;
bool is_launched = common::launch_program (argv,
m_priv->perf_pid,
m_priv->master_pty_fd,
@@ -580,6 +593,7 @@ PerfEngine::annotate_symbol (const UString &a_symbol_name)
argv.push_back (m_priv->record_filepath);
argv.push_back (a_symbol_name);
+ m_priv->is_using_prof_server = false;
bool is_launched = common::launch_program (argv,
m_priv->perf_pid,
m_priv->master_pty_fd,
diff --git a/src/profengine/nmv-perf-server.cc b/src/profengine/nmv-perf-server.cc
index 68baf5c..8f737f0 100644
--- a/src/profengine/nmv-perf-server.cc
+++ b/src/profengine/nmv-perf-server.cc
@@ -50,10 +50,14 @@ static const char *const NMV_DBUS_PROFILER_SERVER_INTROSPECTION_DATA =
" <interface name='org.gnome.nemiver.profiler'>"
" <method name='AttachToPID'>"
" <arg type='i' name='pid' direction='in' />"
+ " <arg type='i' name='uid' direction='in' />"
+ " <arg type='i' name='gid' 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>"
+ " <method name='DetachFromProcess'>"
+ " </method>"
" </interface>"
"</node>";
@@ -84,7 +88,7 @@ struct PerfServer::Priv {
int perf_stderr_fd;
Priv () :
-// subject (polkit_system_bus_name_new ("org.gnome.nemiver")),
+// subject (polkit_system_bus_name_new ("org.gnome.Nemiver")),
bus_id (0),
registration_id (0),
introspection_data (0),
@@ -99,8 +103,9 @@ struct PerfServer::Priv {
}
bool
- on_wait_for_record_to_exit (const Glib::RefPtr<Gio::DBus::MethodInvocation>
- &a_invocation,
+ on_wait_for_record_to_exit (int a_uid, int a_gid,
+ Glib::RefPtr<Gio::DBus::MethodInvocation>
+ a_invocation,
Glib::ustring a_report_filepath)
{
int status = 0;
@@ -114,14 +119,22 @@ struct PerfServer::Priv {
perf_stdout_fd = 0;
perf_stderr_fd = 0;
+ NEMIVER_TRY;
+
Glib::Variant<Glib::ustring> perf_data =
Glib::Variant<Glib::ustring>::create (a_report_filepath);
Glib::VariantContainerBase response =
Glib::VariantContainerBase::create_tuple (perf_data);
+ chown (a_report_filepath.c_str (), a_uid, a_gid);
+
+ std::cout << "Saving report to " << a_report_filepath << std::endl;
+
a_invocation->return_value (response);
+ NEMIVER_CATCH_NOX;
+
return false;
}
@@ -129,7 +142,7 @@ struct PerfServer::Priv {
}
void
- on_new_request (const Glib::RefPtr<Gio::DBus::Connection>&,
+ on_new_request (const Glib::RefPtr<Gio::DBus::Connection> &a_connection,
const Glib::ustring&,
const Glib::ustring&,
const Glib::ustring&,
@@ -140,15 +153,22 @@ struct PerfServer::Priv {
{
NEMIVER_TRY;
+ THROW_IF_FAIL (a_connection);
THROW_IF_FAIL (a_invocation);
if(a_request_name == "AttachToPID") {
Glib::Variant<int> pid_param;
+ Glib::Variant<int> uid_param;
+ Glib::Variant<int> gid_param;
Glib::Variant<std::vector<Glib::ustring> > options_param;
a_parameters.get_child (pid_param);
- a_parameters.get_child (options_param, 1);
+ a_parameters.get_child (uid_param, 1);
+ a_parameters.get_child (gid_param, 2);
+ a_parameters.get_child (options_param, 3);
int pid = pid_param.get ();
+ int uid = uid_param.get ();
+ int gid = gid_param.get ();
std::vector<Glib::ustring> options (options_param.get ());
for (std::vector<Glib::ustring>::iterator iter = options.begin ();
iter != options.end ();
@@ -176,6 +196,8 @@ struct PerfServer::Priv {
argv.push_back (filepath.get ());
argv.insert (argv.end (), options.begin (), options.end ());
+ std::cout << "Launching perf with pid: " << pid << std::endl;
+
bool is_launched =
common::launch_program (argv,
perf_pid,
@@ -185,15 +207,26 @@ struct PerfServer::Priv {
THROW_IF_FAIL (is_launched);
+ std::cout << "Perf started" << std::endl;
+
Glib::RefPtr<Glib::MainContext> context =
Glib::MainContext::get_default ();
context->signal_idle ().connect
- (sigc::bind<const Glib::RefPtr<Gio::DBus::MethodInvocation>, Glib::ustring>
+ (sigc::bind<int, int,
+ Glib::RefPtr<Gio::DBus::MethodInvocation>,
+ Glib::ustring>
(sigc::mem_fun (*this,
&PerfServer::Priv::on_wait_for_record_to_exit),
+ uid, gid,
a_invocation,
filepath.get ()));
}
+ else if (a_request_name == "DetachFromProcess") {
+ kill (perf_pid, SIGINT);
+
+ Glib::VariantContainerBase response;
+ a_invocation->return_value (response);
+ }
else
{
Gio::DBus::Error error
@@ -211,7 +244,7 @@ struct PerfServer::Priv {
(NMV_DBUS_PROFILER_SERVER_INTROSPECTION_DATA);
bus_id = Gio::DBus::own_name
- (Gio::DBus::BUS_TYPE_SESSION,
+ (Gio::DBus::BUS_TYPE_SYSTEM,
NMV_BUS_NAME,
sigc::mem_fun (*this, &PerfServer::Priv::on_bus_acquired),
sigc::mem_fun (*this, &PerfServer::Priv::on_name_acquired),
diff --git a/src/profengine/org.gnome.nemiver.profiler.conf.in b/src/profengine/org.gnome.nemiver.profiler.conf.in
new file mode 100644
index 0000000..946ac30
--- /dev/null
+++ b/src/profengine/org.gnome.nemiver.profiler.conf.in
@@ -0,0 +1,14 @@
+<!DOCTYPE busconfig PUBLIC
+ "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+
+ <policy user="root">
+ <allow own="org.gnome.nemiver.profiler"/>
+ </policy>
+
+ <policy context="default">
+ <allow send_interface="org.gnome.nemiver.profiler"/>
+ </policy>
+
+</busconfig>
diff --git a/src/profengine/org.gnome.nemiver.profiler.service.in b/src/profengine/org.gnome.nemiver.profiler.service.in
new file mode 100644
index 0000000..d55c1d5
--- /dev/null
+++ b/src/profengine/org.gnome.nemiver.profiler.service.in
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=org.gnome.nemiver.profiler
+Exec= NEMIVER_BINDIR@/nmvperfserver
+User=root
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]