Squeak Python Debugger
Squeak Python Debugger
1
PX’17, April 2017, Brussels, Belgium Fabio Niephaus, Tim Felgentreff, Tobias Pape, and Robert Hirschfeld
(a) Eclipse is separate from the language process. (b) Squeak/Smalltalk is part of the language process.
On the other hand, live programming systems, such as Squeak/ We propose the idea to use a Smalltalk environment as an ide
Smalltalk, are well-suited to provide full access to the runtime state for other languages and perform the integration on interpreter-
and provide developers with means to adapt their tools at devel- level. This way, our architecture avoids the n-to-m problems of
opment time according to their needs. In such systems, the ide is interfacing multiple languages by mapping all languages into the
entirely contained in the running process, and thus has full reflec- language of the live environment. This can be achieved by com-
tive access to the state of the system and can directly inspect and posing a Smalltalk interpreter with another language’s interpreter.
manipulate all objects therein, as well as provide edit-and-continue Interpreter composition is especially convenient when both lan-
style debugging (see Figure 1b). guages are implemented in the same interpreter framework, such
However, due to the deep integration with the runtime, tool as RPython [1], as demonstrated in Section 3.
implementations in live, always-on programming environments However, this kind of composition states the problem of how
like Squeak are very language-specific, and even the means to write to run two or more interpreters at the same time. Smalltalk has a
tools do not carry over very well. Thus, even those tools that have concept of processes which can be scheduled dynamically [14]. As
been reproduced for other programming systems have been written we demonstrate later, it is possible to make the execution of a non-
from ground up. Smalltalk interpreter part of a Smalltalk-level process. This way,
We propose an architecture for constructing a multi-language the Smalltalk scheduler decides when to continue with the other
runtime that attempts to combine the benefits of both approaches: interpreter loop, which ensures that the developer can interact with
a common code-base for tool developers and live, immediate access the Smalltalk environment at the same time.
to the running application for inspecting and manipulating state. In such a setup, it is now possible to control interpreters of a for-
Our contributions are as follows: eign language with tools written in Smalltalk. For this to work, the
vm needs to be extended in such a way that it exposes a number of
• An architecture to compose multiple languages within the
interpreter-controlling primitives which can then be called accord-
same live programming environment with reflective capa-
ingly from within a Smalltalk environment. In order to be able to
bilities for full execution control from within the runtime.
execute a program written in another language, primitives for ex-
• An implementation of said architecture using PyPy [21]
ample need to exist which provide an entry point as well as an end
and RSqueak/VM [5, 12].
point for the corresponding interpreter loop. Similarly, primitives
• An implementation of a debugger that works for both,
for restarting and stepping in call frames need to be implemented
Python and Squeak/Smalltalk.
to enable debugging support.
In Section 2 we introduce our approach. Then, we demonstrate Squeak already contains various tools originally demonstrated in
how this approach can be implemented with an example in Sec- Smalltalk-80, including an interactive debugger [13]. Since Squeak’s
tion 3. Afterwards, we discuss advantages and disadvantages of tools are designed to work as part of a framework, it is straight-
our approach in Section 4. Related work is then mentioned in Sec- forward to adopt them, so they can be used for other languages as
tion 5. Finally in Section 6, we conclude the paper and describe well. In addition, new tools, such as application-specific debugging
future work. tools, can quickly be built in Smalltalk [25].
2 APPROACH 3 IMPLEMENTATION
Various interpreted programming languages provide only very lim- We have applied our approach in Section 2, so that we can use
ited debugging support which can be a burden for developers when Squeak/Smalltalk as an ide for Python. The resulting architecture
trying to understand a misbehavior that occurs in their application. of our implementation is depicted in Figure 2. On vm-level, there
On the other hand, Smalltalk is not only a programming language, is an interpreter loop for each language as well as a vm plugin
but also an ide. This means, that the ide is an actual part of the with a set of primitives which allow Smalltalk to interact with the
process running Smalltalk. This gives developers full control over Python bytecode loop. In the Smalltalk image, we have introduced
the running applications and therefore allows for very comprehen- different classes in order to bridge between Python and Smalltalk.
sive debugging tools. In the following, we explain details of this implementation.
2
Squeak Makes a Good Python Debugger PX’17, April 2017, Brussels, Belgium
Figure 2: Architecture of the Smalltalk and Python compo- Figure 3: Mixed-stack Smalltalk and Python execution.
sition.
Squeak frame on the top of the stack. When the Python interpreter
loop switches back to Squeak, the top Python frame 3 creates an
3.1 VM-level Implementation artificial suspended Squeak “resume” frame 4 . When the Squeak
First, we need to build a vm that is capable of executing both, scheduler resumes this artificial frame later, it immediately returns
Smalltalk and Python code. This can be achieved by composing control back to the top Python frame 3 .
a Smalltalk interpreter with a Python interpreter. RSqueak/VM [5] Since interpreters maintain some execution state directly on the
is a RPython-based implementation of Squeak [16], a Smalltalk im- stack, we use Stacklets,4 which are provided by the RPython stan-
plementation derived from Smalltalk-80 and a live programming dard library. Stacklets allow us to implement minimal coroutines
environment. PyPy [21] is a Python implementation and the first for regions of the C stack to switch between the two interpreter
RPython vm. loops. Since this is a feature of the RPython framework and not of
By simply combining the two interpreters, we can create a virtual any specific language implementation, the same principle can also
machine with support for both programming languages. However, be applied to any other interpreter written in RPython.
to use Squeak/Smalltalk as a live development environment for Similar to other Smalltalk vms, RSqueak/VM can be extended
Python, we need to be able to run both interpreters concurrently. with plugins. Not only have we added vm primitives that can be
Smalltalk implements co-operative multitasking through pro- called from within the Smalltalk environment to control the PyPy
cesses [14]. We leverage this and integrate the execution of Python interpreter loop. Since RPython is a subset of Python which com-
bytecodes with a Smalltalk-level process, leaving the decision when piles to C, we were able to build the entire composition in a single
to run the next bytecodes up to the Smalltalk scheduler. This al- PythonPlugin. The code of the plugin for example also patches the
lows us to interact with the Squeak/Smalltalk environment as usual PyPy bytecode loop as well as the class which represents Python
while a Python program is running, as well as to interrupt this pro- frames internally before the actual translation begins. After trans-
cess to inspect it from Smalltalk. lating this new virtual machine, we can open a Squeak/Smalltalk
We create a mixed stack of Python and Smalltalk frames that image and make it aware that the vm also supports the Python
is managed like any other Squeak process (cf. Figure 3). The core programming language.
responsibility of the vm in our approach is to maintain the sender-
relationship 2 – 1 and 4 – 3 across interpreter loops. 3.2 Bridging between Squeak and PyPy
We switch from Squeak to Python by executing a primitive 1 We start by providing a class PythonObject. This class is special,
to enter Python code. This creates a Python frame 2 that executes because the vm will automatically expose objects of the Python ob-
in the Python interpreter loop. When this frame returns, the vm ject space as instances of this new class. In addition, all primitives of
will return from the primitive 1 and transfer control back to its the PythonPlugin are able to automatically convert primitive data
sender. types between Python and Smalltalk. Python strings are therefore
While the Python interpreter is running, we maintain a counter for example converted to Smalltalk ByteStrings and vice-versa.
of how many Python bytecodes have been executed to decide when Now that the vm can inject any kind of Python object into an im-
to transfer control back to Squeak in order to give other processes age, we need be able to interact with these objects. For this reason,
a chance to run (e.g., so that the UI process can handle user in- we have added appropriate primitives to the virtual machine. The
put). Since Python frames are not visible to Squeak and thus the most important primitive is the pythonEval primitive which can
Squeak scheduler cannot switch directly back to Python frames at
a later time, we create an entry point for the scheduler by putting a 4A lightweight threading mechanism in the spirit of tasklets.
3
PX’17, April 2017, Brussels, Belgium Fabio Niephaus, Tim Felgentreff, Tobias Pape, and Robert Hirschfeld
User Interrupt
3.4 Instrumenting more Squeak tools
self.finish_request(request, client_address) (line 318 in lib-python/2.7/SocketServer.py)
self.process_request(request, client_address) (line 290 in lib-python/2.7/SocketServer.py)
self._handle_request_noblock() (line 233 in lib-python/2.7/SocketServer.py)
Similar to the PythonDebugger, we have adopted other tools that
HTTPServer.serve_forever(self) (line 511 in werkzeug/serving.py)
srv.serve_forever() (line 673 in werkzeug/serving.py)
come with Squeak/Smalltalk. It only took little effort to adopt
inner() (line 708 in werkzeug/serving.py)
run_simple(host, port, self, **options) (line 841 in flask/app.py)
Squeak’s interactive Inspector and Explorer tools. Only one
app.run() (line 2 in exec_source.py>)
Python class>>resumeFrame
method needed to be overridden to provide a PythonWorkspace
UndefinedObject>>DoIt which supports Smalltalk-style doIts, printIts, inspectIts, and
exploreIts for Python. Moreover, we have basic Python support
Proceed Restart Into Over Through Full Stack Where Tally
def _handle_request_noblock(self):
"""Handle one request, without blocking. in the SystemBrowser which allows us to create Python classes,
I assume that select.select has returned that the socket is and add Python methods. Finally, it now is possible to rapidly build
readable before this function was called, so there should be
no risk of blocking in get_request().
custom tools for Python development, such as a tool that allows
""" to observe the execution of Python bytecodes which would allow
try:
request, client_address = self.get_request() debugging on Python bytecode level. With for example the Vivide
except socket.error:
return framework [25], one could also build data-flow-based applications
if self.verify_request(request, client_address):
try:
which can consist of Python and Smalltalk code.
self.process_request(request, client_address)
except:
self.handle_error(request, client_address)
self.shutdown_request(request) 4 DISCUSSION
else:
self.shutdown_request(request) This work is aimed at providing the best of two previously sepa-
self
all inst vars
<- Select receiver’s field stack top
all temp vars
a <socket._socketobject rate worlds: the framework approach to cross-language ide and
debugger development provided by environments such as Eclipse
object at
superclass self 0x000000010e948cd0>
methodDict request
format client_address or NetBeans, and the live and immediate debugging nature of sys-
instanceVariables
tems such as Squeak/Smalltalk. On top of that, to be considered
Figure 5: Interrupting a Python application. useful, we seek for an approach that impedes performance of the
integrated languages as little as possible.
def average(iterable):
return sum(iterable) / len(iterable)
7
PX’17, April 2017, Brussels, Belgium Fabio Niephaus, Tim Felgentreff, Tobias Pape, and Robert Hirschfeld
[15] Matthias Grimmer, Chris Seaton, Thomas Würthinger, and Hanspeter Mössen-
böck. 2015. Dynamically Composing Languages in a Modular Way: Sup-
porting C Extensions for Dynamic Languages. In Proceedings of the 14th In-
ternational Conference on Modularity. ACM, New York, NY, USA, 1–13. DOI:
http://dx.doi.org/10.1145/2724525.2728790
[16] Dan Ingalls, Ted Kaehler, John Maloney, Scott Wallace, and Alan Kay. 1997.
Back to the Future: The Story of Squeak, a Practical Smalltalk Written in Itself.
SIGPLAN Not. 32, 10 (Oct. 1997), 318–326. DOI:http://dx.doi.org/10.1145/263700.
263754
[17] Microsoft. 2017. Debugging in Visual Studio. (Jan. 2017). https://msdn.microsoft.
com/en-us/library/sc65sadd(d=default,l=en-us,v=vs.140).aspx
[18] Eliot Miranda. 2011. The Cog Smalltalk Virtual Machine: Writing a JIT in a High-
level Dynamic Language. In 5th Workshop on Virtual Machines and Intermediate
Languages (VMIL).
[19] Michael Perscheid, Michael Haupt, Robert Hirschfeld, and Hidehiko Masuhara.
2012. Test-driven fault navigation for debugging reproducible failures. Infor-
mation and Media Technologies 7, 4 (2012), 1377–1400. DOI:http://dx.doi.org/10.
11185/imt.7.1377
[20] Lukas Renggli, Tudor Gîrba, and Oscar Nierstrasz. 2010. Embedding Languages
without Breaking Tools. In ECOOP 2010 – Object-Oriented Programming: 24th
European Conference, Maribor, Slovenia, June 21-25, 2010. Proceedings, Theo
D’Hondt (Ed.). Springer Berlin Heidelberg, Berlin, Heidelberg, 380–404. DOI:
http://dx.doi.org/10.1007/978-3-642-14107-2_19
[21] Armin Rigo and Samuele Pedroni. 2006. PyPy’s approach to virtual machine
construction. In Companion to the 21st ACM SIGPLAN symposium on Object-
oriented programming systems, languages, and applications (OOPSLA ’06). ACM,
New York, NY, USA, 944–953. DOI:http://dx.doi.org/10.1145/1176617.1176753
[22] Chris Seaton, Michael L. Van De Vanter, and Michael Haupt. 2014. Debug-
ging at Full Speed. In Proceedings of the Workshop on Dynamic Languages and
Applications (Dyla’14). ACM, New York, NY, USA, Article 2, 13 pages. DOI:
http://dx.doi.org/10.1145/2617548.2617550
[23] Matthias Springer. 2016. Inter-language Collaboration in an Object-oriented
Virtual Machine. arXiv preprint (2016). arXiv:1606.03644
[24] Richard M. Stallman, Roland Pesch, and Stan Shebs. 2011. Debugging with GDB:
The GNU Source-Level Debugger, V 7.3.1 (10th ed.). GNU Press, Boston, MA, USA.
[25] Marcel Taeumel, Bastian Steinert, and Robert Hirschfeld. 2012. The VIVIDE
programming environment: connecting run-time information with program-
mers’ system knowledge. In Proceedings of the ACM International Symposium on
New Ideas, New Paradigms, and Reflections on Programming and Software (On-
ward! 2012). ACM, New York, NY, USA, 117–126. DOI:http://dx.doi.org/10.1145/
2384592.2384604
[26] Michael L. Van De Vanter. 2015. Building Debuggers and Other Tools: We Can
"Have It All". In Proceedings of the 10th Workshop on Implementation, Compilation,
Optimization of Object-Oriented Languages, Programs and Systems (ICOOOLPS
’15). ACM, New York, NY, USA, Article 2, 3 pages. DOI:http://dx.doi.org/10.1145/
2843915.2843917
[27] Bret Victor. 2012. Stop drawing dead fish. (May 2012). http://san-francisco.
siggraph.org/stop-drawing-dead-fish/ Talk to the San Fransicso ACM SIG-
GRAPH.