Thursday, 17 February 2011

Sleepless Nights

To quote a colleague
I want gdb to die in a fire. If thats possible.
A sentiment I can only agree with, to be honest. However, it remains in its spread of variably buggy obsolete forms embedded within the development tool chains of too much of the world to avoid. Some notes on living in the land of the clone of the Unix tools from the 1980s. A link to a GDB reference card. Programmable systems (debuggers like GDB, editors like emacs, typesetting systems like LaTeX) have been universally dire in user experience, in _my_ experience. The intended bonus of programmability becomes a curse of necessity; the burden is placed on the user to make the tool usable in the first place. In essence, I want to write programs to solve _my_ problems; not to solve problems in the tools I use; and _not_ to write programs in the debugger while debugging the interesting program or to debug program errors in a document processor.

A set of optparse documentation for common tasks since, as it notes,
we start new project so seldom, it is difficult to remember all those recipes that we come up with, every time we add a new command line option. This article is an attempt to bring together such recipes.

Python can query its environment for the functions in the current module (which is done slightly differently than for _other_ modules). This is useful for auto-testing, saving the need to write out a function list explicitly. Can embed these gist things into a blog post, too.

# Improvement over https://gist.github.com/803854
import optparse
def test_function1():
# Do some test code
# return True on Pass, False on Fail
return True
def test_function2_EXPECTED_FAIL():
# Do some test (more) code
# return True on Pass, False on Fail
return False
def test_functionN():
# Do some test (more) code
# return True on Pass, False on Fail
return False
def main():
parser = optparse.OptionParser()
parser.add_option('-e', '--exit-on-error', dest='exit_on_error',
default=False, action="store_true",
help='Stop running tests on first failure occurring')
parser.add_option('-v', '--verbose', dest='verbose',
default=False, action="store_true",
help='Print each tests name before running')
(opts, args) = parser.parse_args()
tests = []
potential_tests = globals()
# Build list of "test" functions
# here, all functions in the module
for candidate in potential_tests:
# Avoid invoking main, recursively...
if candidate == "main":
continue
elif callable(potential_tests[candidate]):
tests.append(potential_tests[candidate])
failed = []
for t in tests:
if opts.verbose:
print t.__name__
if not t():
if t.__name__.endswith("_EXPECTED_FAIL"):
continue
print t.__name__, "Failed"
failed.append(t.__name__)
if opts.exit_on_error:
return 1
for f in failed :
print "FAIL:",f
if __name__ == "__main__":
main()


After the GDB rant, I confess I don't program gdb much and have not (yet) needed a .gdbinit file to customise GDB in a semi-permanent manner. However, I have some user defined commands to not forget in case I need to stay in GDB a little longer...

define hookpost-step
list
end
define hookpost-stepi
x /i $pc
end
define hookpost-continue
backtrace
end
define contN
set $counter = $arg0
while $counter > 0
continue
set $counter = $counter - 1
end
end
view raw gistfile1.txt hosted with ❤ by GitHub


JGrowl implements growl style notifications in a web page. Cool, if not immediately useful. Also, drop shadows via CSS.

Can fork multiple threads (well, processes) in bash and then join (wait) for the completion of them. Good for parallelism of shell script controlled processes.


cmd_A &
cmd_B &
wait