Debugging tools

Posted on
Sat Apr 02, 2016 1:51 pm
gazally offline
Posts: 27
Joined: Jan 18, 2016
Location: Bigfoot country

Debugging tools

I've built a useful debugging tool. It lets a plugin launch a Terminal.app window with a Python interpreter that is actually running inside the plugin process, so it has live access to the plugin's internal data structures. You can type self.errorLog("I see red") and have it show up in the Indigo log, or you can add a new device and look at self.devices and see if it did what it was supposed to. Here it is on github: https://github.com/gazally/termapp. There's a readme with example code for putting it in a plugin.

It works by starting a thread within the plugin with an instance of code.InteractiveConsole, which is how you make a Python interpreter inside of a Python program, and using Applescript to ask Terminal.app to run a little Python program that gets input lines from the user, sends them to the plugin, gets responses and prints them for the user to see. The plugin thread and the process communicate through named pipes. This works well enough for what I want it to do, but isn't perfect. Perfect would require sockets, telnetlib and curses and be considerably more complicated, but then sys.stdin would work inside the console, whereas right now it gets hooked up to /dev/null.

In the process of figuring out how to do this, I discovered that this (sort of) works from within a plugin.
Code: Select all
from pudb.remote import set_trace   # you'll need to pip install pudb
set_trace(term_size=(80, 24))

And then from Terminal,
Code: Select all
telnet 127.0.0.1 6899

If that port number is taken it will pick a different one and not tell you and this won't work. But if you're lucky, pudb will come up in glorious color. I ran this from a menu command and was able to set a breakpoint in deviceStartComm and look at variables once I got there. But the interactive interpreter in pudb didn't work and then it crashed. I am not much of a debugger user so I didn't pursue it further, but it seems possible that it could be made to work. Or maybe pdb would work using my named pipes method.

Posted on
Wed Apr 06, 2016 9:38 am
matt (support) offline
Site Admin
User avatar
Posts: 21417
Joined: Jan 27, 2003
Location: Texas

Re: Debugging tools

This is really interesting and a great idea. One thought I have is to let InteractiveConsole.interact() handle launching the terminal shell directly, avoiding the need to the client/server paradigm. Here is some of the code for how Indigo's launches its interactive shell:

Code: Select all
import indigo
import readline      # readline import required for command history to work correctly
from code import InteractiveConsole

class Plugin(indigo.PluginBase):
   def _interactivePython(self):
      ver_str = "Python %s\n" % (sys.version)
      ver_str += "Connected to Indigo Server v%s, api v%s (%s:%d)" % (indigo.server.version, indigo.server.apiVersion, indigo.server.address, indigo.server.portNum)

      try:
         shell = InteractiveConsole(globals())
         shell.interact(ver_str)
      finally:
         raise SystemExit("interactive shell shutdown")

   def runConcurrentThread(self):
      self._interactivePython()

You might want to see if that technique can replace at all your pipes/telnet approach? However, there might be reasons why the above approach isn't practical since once control is handed over to the shell it is running on its own. Might be worth trying though.

Image

Posted on
Thu Apr 07, 2016 11:37 am
gazally offline
Posts: 27
Joined: Jan 18, 2016
Location: Bigfoot country

Re: Debugging tools

Hi Matt,
InteractiveConsole.interact() doesn't launch a Terminal window when I try it. When I use ps -x from the command line before and after launching Indigo's shell, here are the new processes:
Code: Select all
18248 ttys001    0:00.00 /bin/bash /Applications/Indigo 6.app/Contents/PlugIns/launch_indigopluginhost.command
18250 ttys001    0:00.59 /Library/Application Support/Perceptive Automation/Indigo 6/IndigoPluginHost.app/Contents/MacOS/IndigoPluginHost -i

So IndigoPluginHost -i is hooking up stdin/stdout/stderr differently for your interactive shell plugin than it does for 3rd party plugins, which are run without -i.

Posted on
Thu Apr 07, 2016 1:26 pm
matt (support) offline
Site Admin
User avatar
Posts: 21417
Joined: Jan 27, 2003
Location: Texas

Re: Debugging tools

You are correct. Apparently I didn't completely remember how it worked. :roll: However, I was able to get it working from inside a plugin. The python code above is correct, but you have to take some extra steps to startup the plugin. Specifically, you have to start the plugin up from the Terminal instead of having the Indigo Server start it. Here is what I did:

1) Added code above to a plugin which is called from within a separate thread when a plugin menu action callback is called. (thread needed to avoid blocking the plugin while the interactive shell is running)

2) Disable the plugin.

3) Manually move the plugin from the Plugins (disabled) folder to the Plugins folder. Ideally this step wouldn't be required, but for the indigopluginhost process to find it it is. I might improve that at some point.

4) From the command line manually start the plugin like this:

Code: Select all
indigohost yourPluginFileName.indigoPlugin

Note this assume you have defined an alias of indigohost to the executable /Library/Application Support/Perceptive Automation/Indigo 6/IndigoPluginHost.app/Contents/MacOS/IndigoPluginHost

5) The plugin should startup. Check the Event Log to see that it is now running.

6) Choose the menu item (or whatever entry point you used) to have the plugin execute the shell.interact method.

If this technique proves useful, then I'll look into adding the functionality to startup a plugin in interactive shell mode to the Indigo Client and Server. It would use a similar technique as the interactive shell, which executes that launch_indigopluginhost.command bash script. That script would in turn open a Terminal shell and call indigohost with the plugin's name to get it started.

Image

Posted on
Thu Apr 07, 2016 3:44 pm
gazally offline
Posts: 27
Joined: Jan 18, 2016
Location: Bigfoot country

Re: Debugging tools

If pdb or pudb is happy running under those conditions, you might have a popular new feature. The disadvantage would be that if you quit Terminal or close the Terminal window the plugin process would get killed, and would it get to call shutdown and exit in an orderly fashion? And you only get one Terminal window per plugin. If you look at the latest version of my Chatbot program, it has two interactive menu commands, one that starts Python and one that lets you interact with your chat scripts by typing messages, and nothing stopping you from using them both together or starting as many of each as you want.

If you could get the existing interactive shell to work with the Indigo Client on a remote machine, that'd be cool. From this conversation I've learned I could use ssh to connect with my mac mini and run IndigoPluginHost -i, but it would be nice if that functionality could be rolled into the existing client-server connection.

Page 1 of 1

Who is online

Users browsing this forum: No registered users and 9 guests

cron