diff options
author | Monroe Linden <monroe@lindenlab.com> | 2009-11-10 15:57:26 -0800 |
---|---|---|
committer | Monroe Linden <monroe@lindenlab.com> | 2009-11-10 15:57:26 -0800 |
commit | 2fd31363f747aaf0ec3d3d6b5711e0ecc99b2cf3 (patch) | |
tree | 0b17d949176aa80dbb0801ac240e36317e5f57e1 | |
parent | 2d5c6ea8207664ed3ef5de356638f7e30b812836 (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.h | 8 | ||||
-rw-r--r-- | indra/llplugin/llpluginclassmedia.cpp | 4 | ||||
-rw-r--r-- | indra/llplugin/llpluginclassmedia.h | 2 | ||||
-rw-r--r-- | indra/llplugin/llpluginprocessparent.cpp | 31 | ||||
-rw-r--r-- | indra/llplugin/llpluginprocessparent.h | 5 | ||||
-rw-r--r-- | indra/newview/app_settings/settings.xml | 11 | ||||
-rw-r--r-- | indra/newview/llviewermedia.cpp | 2 |
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; } |