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.master
parent
2d5c6ea820
commit
2fd31363f7
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue