You are viewing a plain text version of this content. The canonical link for it is here.
Posted to general@gump.apache.org by Leo Simons <ma...@leosimons.com> on 2005/07/05 15:28:06 UTC

[howto] Debugging gump3

Hi gang!

So, ehm, it is possible to run gump through pdb or another debugger
(like wing), but I've found none of those are really of sufficient
quality to be very productive. ye olde "print" statement works as well.
Some clues.

RTFM
----
`./gump help` is your friend. We actually have useful hints in there :-)

Write a unit test
-----------------
Large parts of gump are architected to be pretty easy to test. If you
truly fail to understand what is going on, simply write some test code
that details what you believe should be happening.

The great thing about these tests is that after you've found and fixed a
bug, they serve as a means to prevent the error from ever being
re-introduced.

Loggers
-------
The alternative to print is to use self.log.debug(msg) in most
components. If a component doesn't have access to a logger, add it to
__init__:

def MyComponent:
  def __init__(self, log): # need to add the 'log' argument
    self.log = log # need to add this line

and wherever the component is created (config.py in 99% of the cases)
create a logger and feed it to the component:

  def get_my_component(config):
    from gump.my import MyComponent
    log = get_logger(config, "my") # need to add this
    return MyComponent(log) # need to add the 'log' argument

the advantage of using a logger over simple 'print' statements is that
you can leave them in the code and commit 'em, which means others can
learn from your debug Foo :-)

State
-----
To figure out the "state" of a gump run at any point in the program,
you'll usually want to introspect the model. The good news is that you
can get to the top of the model tree (the workspace) from nearly any
object in the model, eg if you have a Script element, the workspace is at

  script.project.module.repository.workspace

and from there you can introspect the entire tree. Doing that
introspection pretty much involves working with python lists,
dictionaries and a little bit of metaprogramming. Useful tricks include
the 'dir()' command, as well as 'hasattr()', 'getattr()'. It really pays
off to learn a little about python list comprehensions. For example you
may wish to write code like

class MyScriptBuilder(AbstractPlugin):
  def __init__(self, log):
    self.log = log

  def visit_project(self, project):
    for s in [c for c in project.commands if isinstance(c, Script)]:
      self.handle_script(script)

  def handle_script(self, script):
    # AARGH! What on earth is going on here????
    if script.project.name == "bootstrap-ant":
      plist = \
        script.project.module.repository.workspace.projects.values()
      for problem in [p for p in plist if check_failure(p)]:
        self.log.debug("Project %s failed!" % script.project.name)

"Debug probe"
-------------
I've built and committed a little plugin called the IntrospectionPlugin
(which is enabled when you pass --debug on the command line) which
provides a nice place to do run the kinds of debug snippets as hinted at
above. It gets run last just before gump exits, so its output is last on
the console.

It has some sample code in there showing off the power of a few dir()
statements along with some list comprehensions. Putting your debug code
in that central place (instead of directly inside your MyScriptBuilder)
is very useful if you're dealing with exceptions you don't fully grok.
Simply try and recreate the problem inside the IntrospectionPlugin: it
can often provide useful clues. For me, often, some weird error is
caused by me making some weird typo, and simply writing a little bit of
code from scratch helps isolate the problem.

Use color
---------
If you've got a terminal that supports colored output (you don't? What
age are you from??), pass gump the --color argument to make log output a
lot more readable. To quickly find a debug message in the many lines of
output gump generates, add a little color yourself. In the above
example, you'd maybe want to

  from gump.util import ansicolor
  self.log.debug(
    "%sProject %s failed!%s" % \
    (ansicolor.Red, script.project.name, ansicolor.Black))

Do note that gump pretty much is geared for
black-text-on-white-background, so if you have your terminal configured
with a black background, you won't be seeing much at all :-)


hope this helps!

cheers,

Leo

---------------------------------------------------------------------
To unsubscribe, e-mail: general-unsubscribe@gump.apache.org
For additional commands, e-mail: general-help@gump.apache.org


Re: Getting project file name from module

Posted by Leo Simons <ma...@leosimons.com>.
Hi Justin!

Justin Merz wrote:
> Since gump3 does not recoginze maven project descriptor files I am
> trying to access the file name from the module descriptor file (/tag if
> in same file). 

Actually, I think that gump, in the form of the Loader component,
manages to load the descriptor just fine. Eg it if you have

<workspace>
  ...
  <projects>
    ...
    <project href="somemavendescriptor.xml">
    </project>
  </projects>
  ...
</workspace>

then the Loader will get hold of somemavendescriptor.xml, and replace
said <project/> with the contents of that descriptor. But my memory is a
bit sketchy, and that's probably not tested. Might be a good idea ;)

> I believe the project descriptor tag is removed from the
> module file and placed into a dropped_tags list.

Hmm. I don't think so. I think after the "loading" stage is complete the
descriptors are still in the workspace.

> Is there anyway to
> access this list ie functions already written

Not really, but Engine._write_merge_files() does iterate over that list
and writes a new xml file. You might find it helpful. And the other bits
of gump.engine do a lot of xml manipulation to spy on. But no doubt
you're still going to have to figure out loads of DOM stuff :-)

See http://www.python.org/doc/current/lib/module-xml.dom.html

> or does anyone have a
> better idea how to access all of module's data by the time normalizer
> gets ahold of it?

In the example above, maybe we could have

<workspace>
  ...
  <projects>
    ...
    <project type="maven" href="somemavendescriptor.xml">
    </project>
  </projects>
  ...
</workspace>

And then you could build a Mavenizer component that does something like this

  projects = w.getElementsByTagName("project")
  for p in [p for p projects if p.getAttribute("type") == "maven"]:
      magic_goes_here()

Or maybe there's a good way to detect that we're dealing with a maven
definition (eg if all maven xml files always have a pomVersion or
something). I dunno. If you do an 'svn log' on normalizer.py and/or look
through the mailing list archives you might find ideas some of us had at
some point. But I'd just do the thinking myself if I were you ;)

> PS. please let me know if you think i am going in the wrong direction on
> this!

Nope, just keep going :-). Once you've got your first patch together
I'll try and give you more feedback to shake a stick at :-)

cheers,

Leo

---------------------------------------------------------------------
To unsubscribe, e-mail: general-unsubscribe@gump.apache.org
For additional commands, e-mail: general-help@gump.apache.org


Getting project file name from module

Posted by Justin Merz <jr...@ucdavis.edu>.
Group,

Since gump3 does not recoginze maven project descriptor files I am 
trying to access the file name from the module descriptor file (/tag if 
in same file).  I believe the project descriptor tag is removed from the 
module file and placed into a dropped_tags list.  Is there anyway to 
access this list ie functions already written or does anyone have a 
better idea how to access all of module's data by the time normalizer 
gets ahold of it?

-Thanks
Justin

PS. please let me know if you think i am going in the wrong direction on 
this!

---------------------------------------------------------------------
To unsubscribe, e-mail: general-unsubscribe@gump.apache.org
For additional commands, e-mail: general-help@gump.apache.org


Re: [howto] Debugging gump3

Posted by Justin Merz <jr...@ucdavis.edu>.
Thanks!  thats my favorite kind of discount ... free!  I have used 
debuggers before ie. gdb and ddd (which i think just runs gdb) but thats it.

-Justin

Leo Simons wrote:

>Leo Simons wrote:
>  
>
>>So, ehm, it is possible to run gump through pdb or another debugger
>>(like wing), but I've found none of those are really of sufficient
>>quality to be very productive. ye olde "print" statement works as well.
>>    
>>
>
>So, ehm, *cough*, I actually found myself explaining to adam the other
>day how useful the Wing IDE debugger can be. I just committed some stuff
>that hopefully makes it real easy to use either wing or PDB for
>debugging. Let me know if it doesn't work.
>
>Justin, you might want to try this out. You can get a free license to
>Wing IDE for working on open source software (see
>http://wingware.com/store/prices#discounts).
>
>cheers,
>
>Leo
>
>Using a Real Debugger(tm) with Gump3
>------------------------------------
>Running `./gump help` shows two debug-related command line options:
>
>    debug           -- run pygump in debug mode, attaching pdb
>    debug-with-wing -- run pygump in debug mode, attaching the Wing IDE
>
>Which have docs:
>
>[lsimons@giraffe]$ ./gump help debug
>
>
>      Run pygump in debug mode.
>
>      Usage:
>        ./gump debug [gump.py-args ...]
>
>   This is not the same as executing the 'run' command with a '--debug'
>   parameter. Using this command will actually start the command line
>   debugger pdb to run gump in, whereas the '--debug' option customizes
>   the log verbosity gump will use.
>
>   This command otherwise accepts the same arguments as the 'run'
>   command.
>
>[lsimons@giraffe]$ ./gump help debug-with-wing
>
>                              Gump3
>
>      Run pygump in debug mode.
>
>      Usage:
>        ./gump debug [gump.py-args ...]
>
>  This is not the same as executing the 'run' command with a '--debug'
>  parameter. Using this command will actually start the debug connector
>  for the Wing IDE and attach it to the gump process, whereas the
>  '--debug' option customizes the log verbosity gump will use.
>
>  This command otherwise accepts the same arguments as the 'run'
>  command.
>
>Usage is something like this:
>
>  ./gump debug -w \
>    /home/lsimons/svn/gump/branches/Gump3/fixture/metadata/workspace.xml
>
>or for wing ide:
>
>  export WINGHOME=path/to/wing/2
>  ./gump debug-with-wing -w \
>    /home/lsimons/svn/gump/branches/Gump3/fixture/metadata/workspace.xml
>
>If you've not worked with debuggers before, you should probably take
>some time to review the relevant documentation for your choice of
>
>  - PDB: http://www.ferg.org/papers/debugging_in_python.html
>  - Wing IDE: http://wingware.com/doc/debug/index
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: general-unsubscribe@gump.apache.org
>For additional commands, e-mail: general-help@gump.apache.org
>  
>


---------------------------------------------------------------------
To unsubscribe, e-mail: general-unsubscribe@gump.apache.org
For additional commands, e-mail: general-help@gump.apache.org


Re: [howto] Debugging gump3

Posted by Leo Simons <ma...@leosimons.com>.
Leo Simons wrote:
> So, ehm, it is possible to run gump through pdb or another debugger
> (like wing), but I've found none of those are really of sufficient
> quality to be very productive. ye olde "print" statement works as well.

So, ehm, *cough*, I actually found myself explaining to adam the other
day how useful the Wing IDE debugger can be. I just committed some stuff
that hopefully makes it real easy to use either wing or PDB for
debugging. Let me know if it doesn't work.

Justin, you might want to try this out. You can get a free license to
Wing IDE for working on open source software (see
http://wingware.com/store/prices#discounts).

cheers,

Leo

Using a Real Debugger(tm) with Gump3
------------------------------------
Running `./gump help` shows two debug-related command line options:

    debug           -- run pygump in debug mode, attaching pdb
    debug-with-wing -- run pygump in debug mode, attaching the Wing IDE

Which have docs:

[lsimons@giraffe]$ ./gump help debug


      Run pygump in debug mode.

      Usage:
        ./gump debug [gump.py-args ...]

   This is not the same as executing the 'run' command with a '--debug'
   parameter. Using this command will actually start the command line
   debugger pdb to run gump in, whereas the '--debug' option customizes
   the log verbosity gump will use.

   This command otherwise accepts the same arguments as the 'run'
   command.

[lsimons@giraffe]$ ./gump help debug-with-wing

                              Gump3

      Run pygump in debug mode.

      Usage:
        ./gump debug [gump.py-args ...]

  This is not the same as executing the 'run' command with a '--debug'
  parameter. Using this command will actually start the debug connector
  for the Wing IDE and attach it to the gump process, whereas the
  '--debug' option customizes the log verbosity gump will use.

  This command otherwise accepts the same arguments as the 'run'
  command.

Usage is something like this:

  ./gump debug -w \
    /home/lsimons/svn/gump/branches/Gump3/fixture/metadata/workspace.xml

or for wing ide:

  export WINGHOME=path/to/wing/2
  ./gump debug-with-wing -w \
    /home/lsimons/svn/gump/branches/Gump3/fixture/metadata/workspace.xml

If you've not worked with debuggers before, you should probably take
some time to review the relevant documentation for your choice of

  - PDB: http://www.ferg.org/papers/debugging_in_python.html
  - Wing IDE: http://wingware.com/doc/debug/index

---------------------------------------------------------------------
To unsubscribe, e-mail: general-unsubscribe@gump.apache.org
For additional commands, e-mail: general-help@gump.apache.org