Find bugs by sabotaging code

Greg Ward greg at gerg.ca
Tue Jun 30 21:15:24 CDT 2009


So the other night, I was doing some exploratory hacking to try to
understand some of the guts of Mercurial.  (Long story.)  At some
point, I was curious why/when/from where dirstate.invalidate() was
being called.  So I sabotaged it to get a traceback:

--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -214,6 +214,7 @@
             self._pl = p

     def invalidate(self):
+        raise RuntimeError()
         for a in "_map _copymap _foldmap _branch _pl _dirs _ignore".split():
             if a in self.__dict__:
                 delattr(self, a)

Obviously I didn't care about, say, committing anything -- just
figuring out how things fit together.

This little act of sabotage seems to expose some interesting lurking
bugs in and around lock.py.  For example, if I attempt a no-change
commit:

  $ hg ci -m'foo'
  /home/greg/src/hg-crew/mercurial/lock.py:76: DeprecationWarning: use
lock.release instead of del lock

Problem #1: something in the vicinity of lock.trylock() seems to be
letting a lock object go out of scope, triggering the deprecation
warning.

  ** unknown exception encountered, details follow
  ** report bug details to http://mercurial.selenic.com/bts/
  ** or mercurial at selenic.com
  ** Mercurial Distributed SCM (version 7b3d837ca60e)
  ** Extensions loaded: qct, hgk, children, graphlog, purge, convert,
record, mq, rebase, patchbomb, extdiff, attic
  Traceback (most recent call last):
    File "/home/greg/bin/hg", line 27, in <module>
      mercurial.dispatch.run()
    [...]
    File "/home/greg/src/hg-crew/mercurial/dirstate.py", line 219, in invalidate
      raise RuntimeError()
  RuntimeError
  Exception exceptions.TypeError: "'NoneType' object is not iterable"
in <bound method lock.__del__ of <mercurial.lock.lock object at
0x834fa2c>> ignored

Problem #2: exception in lock.__del__().  I added some "print"
statements and determined that two separate lock objects are at play
here.

I don't think either of these are terribly serious, given that I had
to sabotage the code to provoke them.  But a user might trigger
KeyboardInterrupt where I inserted RuntimeError, so either one could
happen in real life.  But after perusing the code for 20-30 min, I
don't really have a clue what the problems are or how to fix them.
Just thought I'd report in before reverting my sabotage patch.

Greg


More information about the Mercurial-devel mailing list