summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonroe Linden <monroe@lindenlab.com>2009-11-10 15:57:26 -0800
committerMonroe Linden <monroe@lindenlab.com>2009-11-10 15:57:26 -0800
commit2fd31363f747aaf0ec3d3d6b5711e0ecc99b2cf3 (patch)
tree0b17d949176aa80dbb0801ac240e36317e5f57e1
parent2d5c6ea8207664ed3ef5de356638f7e30b812836 (diff)
Added PluginAttachDebuggerToPlugins debug setting.
Added accessors to get platform-specific process ID from LLProcessLauncher. Added an optional "debug" argument to LLPluginClassMedia::init() and LLPluginProcessParent::init() (defaults to false). Mac only: made the state machine in LLPluginProcessParent::idle() open a new window in Terminal.app with a gdb session attached to the plugin process upon successful launch.
-rw-r--r--indra/llcommon/llprocesslauncher.h8
-rw-r--r--indra/llplugin/llpluginclassmedia.cpp4
-rw-r--r--indra/llplugin/llpluginclassmedia.h2
-rw-r--r--indra/llplugin/llpluginprocessparent.cpp31
-rw-r--r--indra/llplugin/llpluginprocessparent.h5
-rw-r--r--indra/newview/app_settings/settings.xml11
-rw-r--r--indra/newview/llviewermedia.cpp2
7 files changed, 56 insertions, 7 deletions
diff --git a/indra/llcommon/llprocesslauncher.h b/indra/llcommon/llprocesslauncher.h
index 880562157f..929d547f6e 100644
--- a/indra/llcommon/llprocesslauncher.h
+++ b/indra/llcommon/llprocesslauncher.h
@@ -70,6 +70,14 @@ public:
// This needs to be called periodically on Mac/Linux to clean up zombie processes.
static void reap(void);
+
+ // Accessors for platform-specific process ID
+#if LL_WINDOWS
+ HANDLE getProcessHandle() { return mProcessHandle; };
+#else
+ pid_t getProcessID() { return mProcessID; };
+#endif
+
private:
std::string mExecutable;
std::string mWorkingDir;
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 457c074ef1..42d5ec49cd 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -61,14 +61,14 @@ LLPluginClassMedia::~LLPluginClassMedia()
reset();
}
-bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_filename)
+bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug)
{
LL_DEBUGS("Plugin") << "launcher: " << launcher_filename << LL_ENDL;
LL_DEBUGS("Plugin") << "plugin: " << plugin_filename << LL_ENDL;
mPlugin = new LLPluginProcessParent(this);
mPlugin->setSleepTime(mSleepTime);
- mPlugin->init(launcher_filename, plugin_filename);
+ mPlugin->init(launcher_filename, plugin_filename, debug);
return true;
}
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 90ecd1e073..dcc4a3bd6a 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -47,7 +47,7 @@ public:
virtual ~LLPluginClassMedia();
// local initialization, called by the media manager when creating a source
- virtual bool init(const std::string &launcher_filename, const std::string &plugin_filename);
+ virtual bool init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug = false);
// undoes everything init() didm called by the media manager when destroying a source
virtual void reset();
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 39f9438fb3..b7ce800c3a 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -55,6 +55,7 @@ LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner)
mBoundPort = 0;
mState = STATE_UNINITIALIZED;
mDisableTimeout = false;
+ mDebug = false;
// initialize timer - heartbeat test (mHeartbeat.hasExpired())
// can sometimes return true immediately otherwise and plugins
@@ -96,11 +97,12 @@ void LLPluginProcessParent::errorState(void)
setState(STATE_ERROR);
}
-void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_filename)
+void LLPluginProcessParent::init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug)
{
mProcess.setExecutable(launcher_filename);
mPluginFile = plugin_filename;
mCPUUsage = 0.0f;
+ mDebug = debug;
setState(STATE_INITIALIZED);
}
@@ -291,6 +293,31 @@ void LLPluginProcessParent::idle(void)
}
else
{
+ if(mDebug)
+ {
+ #if LL_DARWIN
+ // If we're set to debug, start up a gdb instance in a new terminal window and have it attach to the plugin process and continue.
+
+ // The command we're constructing would look like this on the command line:
+ // osascript -e 'tell application "Terminal"' -e 'set win to do script "gdb -pid 12345"' -e 'do script "continue" in win' -e 'end tell'
+
+ std::stringstream cmd;
+
+ mDebugger.setExecutable("/usr/bin/osascript");
+ mDebugger.addArgument("-e");
+ mDebugger.addArgument("tell application \"Terminal\"");
+ mDebugger.addArgument("-e");
+ cmd << "set win to do script \"gdb -pid " << mProcess.getProcessID() << "\"";
+ mDebugger.addArgument(cmd.str());
+ mDebugger.addArgument("-e");
+ mDebugger.addArgument("do script \"continue\" in win");
+ mDebugger.addArgument("-e");
+ mDebugger.addArgument("end tell");
+ mDebugger.launch();
+
+ #endif
+ }
+
// This will allow us to time out if the process never starts.
mHeartbeat.start();
mHeartbeat.setTimerExpirySec(PLUGIN_LAUNCH_SECONDS);
@@ -661,7 +688,7 @@ bool LLPluginProcessParent::pluginLockedUpOrQuit()
{
bool result = false;
- if(!mDisableTimeout)
+ if(!mDisableTimeout && !mDebug)
{
if(!mProcess.isRunning())
{
diff --git a/indra/llplugin/llpluginprocessparent.h b/indra/llplugin/llpluginprocessparent.h
index 754ebeb946..1289e86c13 100644
--- a/indra/llplugin/llpluginprocessparent.h
+++ b/indra/llplugin/llpluginprocessparent.h
@@ -56,7 +56,7 @@ public:
LLPluginProcessParent(LLPluginProcessParentOwner *owner);
~LLPluginProcessParent();
- void init(const std::string &launcher_filename, const std::string &plugin_filename);
+ void init(const std::string &launcher_filename, const std::string &plugin_filename, bool debug = false);
void idle(void);
// returns true if the plugin is on its way to steady state
@@ -150,6 +150,9 @@ private:
F64 mCPUUsage;
bool mDisableTimeout;
+ bool mDebug;
+
+ LLProcessLauncher mDebugger;
};
#endif // LL_LLPLUGINPROCESSPARENT_H
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 55ff255c38..15c9499bbc 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -5327,6 +5327,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>PluginAttachDebuggerToPlugins</key>
+ <map>
+ <key>Comment</key>
+ <string>If true, attach a debugger session to each plugin process as it's launched.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>PluginInstancesCPULimit</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 69650425cb..66d48fadd1 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -847,7 +847,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
{
LLPluginClassMedia* media_source = new LLPluginClassMedia(owner);
media_source->setSize(default_width, default_height);
- if (media_source->init(launcher_name, plugin_name))
+ if (media_source->init(launcher_name, plugin_name, gSavedSettings.getBOOL("PluginAttachDebuggerToPlugins")))
{
return media_source;
}