2007년 6월 11일 월요일

pyprof progresses

It has been a week since the beginning of pyprof. The project is progressing well.

The code is in the usual place:
https://fepy.svn.sourceforge.net/svnroot/fepy/trunk/pyprof/

There are some Makefile updates. Some variables are now defined at the top of the file. You may want to change the path to Mono, Python, and IronPython there.

I wrote a call tracer in pure Python using sys.setprofile which should print the essentially same output as pyprof. The filename is prof.py, and you can type "make testpy" to see its output. Compare the output with one from "make test".

You can type "make test.out" to update the reference output. This file is quite long, as I swapped the sample script to one using nntplib from the Python standard library. The script connects to Gmane and print the description of comp.lang.python newsgroup.

Some new features of the call tracer includes obvious ones like printing method leave events, and indenting messages to show the call depth. After some refactoring, logic for filtering non-Python assemblies and IronPython-internal methods now live in the separate function. I plan to split them to the separate file actually.

IronPython-internal TryGetExtraValue calls are now ignored. This was obvious once I moved to profiling real programs.

In the last post, I wrote that test output assumes you have blank site.py. Then I remembered that Python has a command line option -S to disable importing of site.py. Unfortunately, this revealed a bug in IronPython. I reported the bug to the IronPython mailing list and wrote a patch to fix it.

Development of pyprof also revealed a bug in the Mono runtime. When the method is left by throwing an exception, the profiler was not notified about the event. This is problematic, because the Python Library Reference specifies about sys.setprofile (link) that "the return event is reported even when an exception has been set".

I reported the bug to the Mono mailing list and subsequently wrote a 4-line patch. That patch actually took 4 hours to come with (a line per an hour :-), but I learned a lot in the process. Miguel de Icaza promptly applied the patch for me.

Now I need to look at the profiling API for Microsoft .NET runtime, as demanded by Michael Foord.

2007년 6월 4일 월요일

pyprof: Mono profiler for IronPython

CPython distribution comes with debuggers and profilers. More importantly, it comes with hooks so that you can write your own debuggers and profilers. You can set these hooks by built-in functions sys.settrace and sys.setprofile.

Here is what Python Library Reference says about sys.settrace (link):

settrace(tracefunc)

Set the system's trace function, which allows you to implement a Python source code debugger in Python. See section 24.2, "How It Works," in the chapter on the Python debugger. The function is thread-specific; for a debugger to support multiple threads, it must be registered using settrace() for each thread being debugged. Note: The settrace() function is intended only for implementing debuggers, profilers, coverage tools and the like. Its behavior is part of the implementation platform, rather than part of the language definition, and thus may not be available in all Python implementations.


In other words, another Python implementation like IronPython is within its own right not to implement these functions. As a matter of fact:

IronPython 1.1 (1.1) on .NET 2.0.50727.42
Copyright (c) Microsoft Corporation. All rights reserved.
>>> sys.settrace(f)
Traceback (most recent call last):
NotImplementedError: sys.settrace is not yet supported by IronPython
>>> sys.setprofile(f)
Traceback (most recent call last):
AttributeError: 'module' object has no attribute 'setprofile'


Don't get this wrong, this is fully okay. Both .NET Framework and Mono have their set of tools to do debugging, profiling, tracing, and coverage, often better than what CPython provides.

But when you debug a Python program, usually you don't need to single step inside Python runtime. When you trace a Python program, you don't necessarily want to know how a single line of Python code expands to 20 low-level function calls. So it's desirable to restrict tools to Python methods only.

Enter pyprof.

pyprof is a Mono profiler for IronPython. Mono provides an interface to write custom profilers, and there are quite some of them. pyprof uses this API to query a custom attribute, IronPython.Runtime.PythonModuleAttribute from method's defining assembly. Messages are printed only if the attribute is present.

The code is here:
https://fepy.svn.sourceforge.net/svnroot/fepy/trunk/pyprof/

Type "make test" to see what it can do. It should print the output in test.out file. (This assumes that you have blank site.py. The output will differ if you don't.)

Disclaimer: pyprof is a less-than-a-day old software. Don't expect much. But I do have great plans for this baby. :-)

Hello, world!

Due to peer pressure, I decided to start a blog. I will talk about the development of FePy project here.

FePy project