A Conceptual Model for Visualising Concurrent Java Programs Using

6 downloads 0 Views 644KB Size Report
such as Java, C# and VB. ... This is an issue because in concurrent programs threads compete against each other for ..... this issue by associating a colour to each object. ... The Thread State Diagram consists of six interconnected states ..... Learning II", Available: http://www.agocg.ac.uk/reports/graphics/capture2/capture.pdf ...
A Conceptual Model for Visualising Concurrent Java Programs Using UML Hugo Leroux, Christine Mingins and Annya Réquilé-Romanczuk School of Computer Science and Software Engineering Monash University 900 Dandenong Road Caulfield East, Victoria 3145, Australia Telephone: +61 3 9903 1965

[1] @csse.monash.edu.au ABSTRACT Understanding concurrent object-oriented software execution is not a trivial task. This is mainly due to the interleaving of threads, and multiple flows of control that result in different outputs being produced at successive executions of the program. We believe that visualisation can be of assistance to developers in expediting the comprehension of concurrent object-oriented software. In this paper, we discuss the issues associated with concurrency and the challenges faced when attempting to display these issues visually. We present Jacot, an environment to exemplify the intricacies of concurrency in Java at run-time. This environment is based on the Unified Modeling Language (UML) paradigm and uses the Java Debug Interface (JDI) for event gathering. The visualisation model also defines extensions to be made to the UML to incorporate concurrency constructs. The originality of this research is its aim at completeness of representation of concurrency issues. Keywords Concurrency, Object-Orientation, Visualisation, UML, Software Tools, Information Retrieval.

1. INTRODUCTION Recently, there has been an emergence of multithreaded (concurrent) programming among the IT community. This has mostly been sparked by a need for greater processing power as complex applications such as weather forecasting, stock market predictions and graphic rendering tasks, need to be executed in a shorter time frame. Universities have responded by rapidly introducing concurrency in the undergraduate curriculum. Similarly many emerging programming languages such as Java, C# and VB.Net, have concurrency inbuilt in the language. As Kraemer said, “understanding the behaviour of concurrent programs is more challenging than understanding the behaviour of sequential programs”[2]. In a sequential environment, developers are assisted by a wide range of integrated development environments (IDEs) offering them design, analysis and debugging tools. However, there is a lack of such IDEs to assist developers in a multithreaded environment.

This is particularly true with regard to debugging existing 1

concurrent object-oriented software. Many of the concepts of sequential programming, used in debugging, do not migrate well into multi-threaded programming. Traditional methods such as analysing the source code and looking at sample outputs do not suffice to gain a proper understanding of the program and for debugging purposes in a multithreaded environment. This is an issue because in concurrent programs threads compete against each other for shared resources, such as memory and CPU cycles. There can be multiple flows of control and indeed execution of the same program may result in very different output due to the inherent non-determinism of threads. Furthermore, unlike sequential programming where a program is almost guaranteed to complete, once it is started, this is not always the case with a multi-threaded program. Dijkstra [3] stated, “our intellectual powers are rather geared to master static relations and our powers to visualize processes evolving in time are poorly developed”. Software visualisation uses a blend of colours, space, text and shapes to provide the developer with a model of the dynamics of the software under study. It is our belief that visualisation, when adequately used, can be of assistance in expediting our comprehension of concurrent objectoriented software. This belief is strengthened by a report by Williams et al. [4] on the use of images in computer-based learning. We present Jacot (an acronym for JAva Concurrent Object Tool), a visualisation tool that takes a concurrent Java program, as input, and dynamically visualises its execution. The main aim of the tool is to address the challenges associated with understanding the execution of concurrent Java programs. The paper is organised as follows. We start by stating, in section 2, the most common challenges of concurrency that the programmer is faced with and briefly outline how visualisation can be of assistance. We proceed, in Section 3, by discussing the rationale associated with proposing a conceptual model of our visualisation tool to attend to those issues. Our discussion focuses primarily on the functionality, graphical model and display of the views. This is followed, in Section 4, by an outline of the underlying architecture of Jacot. We look at the advantages of using Java as an implementation platform in terms of language support for concurrency, event gathering and visualisation. In section 5, we outline some of our implementation decisions. In Section 6, we present a running example of a concurrency problem visualised through Jacot. We then comment, in Section 7, on how some of existing visualisation tools addresses the concurrency issues. Finally, we conclude and give an outlook of future work within the research.

2. ISSUES IN CONCURRENCY Concurrent object-oriented programs are more difficult to design, implement and maintain than sequential programs. During the design phase, meticulous attention must be given to balancing the safety and liveness aspects of the program. In the context of designing a multithreaded program, designing for safety is easier as it is more tangible, whereas liveness is harder to express and ensure. However, improving safety is often detrimental to liveness in a program.

2

2.1 Liveness Liveness in a concurrent program involves ensuring that resources within the program never fail to execute or become “live”. One common definition of Liveness asserts: “something eventually happens”[5]. Liveness failures are often encountered by programming novices, who in an attempt to ensure safety over-synchronise the access to resources, resulting in a blocked program, which fails to execute. There are four inter-related cases that may cause a liveness failure. They are: i.

Contention (Starvation) Contention occurs when a thread fails to obtain CPU time. This could be a scheduling problem: a thread is assigned a lower priority than other threads; or a fairness problem: waiting threads are placed in a pool and get woken up arbitrarily.

ii.

Dormancy Dormancy is the result of a non-runnable thread that fails to become runnable, normally as a result of a wait command not followed by a notify or notifyAll. This could also hide a synchronisation problem whereby a thread is notified before it has started waiting, thus never being woken up.

iii.

Deadlock When two or more threads mutually block one another holding the lock to one object, while desperately attempting to acquire the lock held by the other thread, a deadlock is deemed to have occurred. Coffman, Elphick and Shoshani [6] identified four necessary and sufficient conditions for the occurrence of deadlock in a program. These are: •

Serially reusable resources



Incremental acquisition



No pre-emption



Wait-for-cycle

The interested reader is referred to [6] for further information about these four conditions. iv.

Premature termination A premature termination occurs when a thread is stopped or terminated before its natural death in a program. This is often the result of an uncaught exception happening in the program. Premature termination of threads can be particularly problematic, especially in large programs, as the thread termination may go unnoticed, while the rest of the program continues to execute.

We believe that visualisation techniques can assist the novice programmer understand the issues associated with liveness by analysing the execution of the threads within the program. The activation or inactivation of threads, as

3

would be case for dormancy and starvation, should help shed light on any liveness problems arising within the program. This is further explored in section 3.5

2.2 Safety Ensuring safety in a concurrent program involves ensuring that the program never reaches a spurious state. Indeed a common definition of safety asserts: “nothing bad ever happens”[5]. Lea [5] defines three basic strategies to ensure that safety is maintained in a concurrent program. These are: i.

Immutability Immutability is concerned with avoiding state changes of the objects in the program. If the state of an object cannot be changed, then, logically, it can never reach an illegal state.

ii.

Synchronisation Synchronisation is concerned with dynamically ensuring exclusive access to data members of an object. The most common mechanism for synchronisation in a concurrent program is to use locks. In Java[7], every instance of the class Object possesses a lock1.

iii.

Containment Containment ensures exclusive access to a particular object by making use of encapsulation to ensure that at most one thread executes within the object at any given time. Like all other forms of encapsulation, the inner object is protected from unwanted external access by the outer object from which it obtains its lock. However, considerable care must be taken to prevent the contained object from passing a reference to itself out of the container object. Containment can exist across methods, within threads and within objects [5]

The two main safety issues commonly encountered in a concurrent program are data integrity and data race condition. Data integrity is concerned with ensuring that the data invariants are obeyed throughout the entire execution. For example if two threads A and B are executing in a program. Both threads read data variable X simultaneously. Assume that A increments X by 10 and writes it back. Then B increments X by 5 and writes it back. Then the operation by thread A is lost by the operation by thread B. Data race condition ensures that a data item is not ‘consumed’ before it is ‘produced’. For example, assume threads A and B both operate on a fixed stack. A is responsible for adding new items to the stack, while B removes items from the stack. B cannot remove any items until A has placed at least one item on the stack. Similarly, as the stack fills up, A cannot add any more items until B has removed at least one. Jacot cannot, as currently modelled, depict most Safety issues effectively. This is because Jacot provides a high-level abstraction of the entire execution of the concurrent program, whereas data integrity issues are related to objects and

1

As every class, library and user-defined, in Java inherits from the class Object, it also possesses a lock. 4

their attributes. In the case of data integrity, it may be helpful to allow the user to inspect the value of variables during execution. This however is outside the scope of Jacot. We believe that these problems are more suited to visual debuggers such as the Omniscient Debugger [8]. However, we are able to depict synchronisation and race conditions by animating the locking mechanisms of the object by threads executing therein. This is further discussed in section 3.4.6.

3. DESIGN DECISIONS Having presented some justifications for the use of visualisation techniques to assist in the understanding of complex concurrent programming techniques, we now present an overview of the desirable characteristics of a visualisation tool. This overview serves two purposes: (1) It can help with the evaluation of existing visualisation tools and; (2) It can form the basis of design decisions for new visualisation tools as is the case in this research. These characteristics can be considered in terms of functionality, graphical model, execution mode and display.

3.1 Functionality The visualisation tool should depict: i.

The dynamic creation, update and deletion of the objects executing;

ii.

Useful information relating to method invocations;

iii.

The dynamic creation and termination of threads together with their current status;

iv.

The interleaving of threads;

v.

The thread which at time t, possesses the lock to a particular object O (the object’s monitor);

vi.

The number of threads that belong to a particular object;

vii.

The synchronisation of critical sections within the program

3.2 Graphical Model The Unified Modeling Language (UML) [9] paradigm is the logical choice for our graphical model. The main rationale behind our choice is that UML is the de facto language for modelling object-oriented systems in industry and academia, where it is widely accepted and utilised [10]. This, we hope, will accentuate its acceptance as a medium for visualisation of executing software. More specifically, for Jacot, we find that the Sequence diagram model is appropriate. A Sequence diagram is well suited as a basis for visualising software execution as it has an explicit time axis. It is also powerful in demonstrating the interaction between objects by illustrating method invocations. Furthermore, the combination of the time dimension and message-passing capabilities allow for the interleaving of events to be clearly depicted.

5

However, UML Sequence diagrams are somewhat limited in their representation of concurrent software execution. As a result, we propose some extension constructs and concepts to be added to the Sequence diagram. Furthermore, we borrow some of the notation and concepts of the UML Statechart diagram to propose a Thread State Diagram to depict and monitor the state of the threads during execution. We outline the extensions made to the UML in section 3.4.

3.3 Execution Mode One of the main research questions in the literature is the modus operandi of the visualisation system. Should the visualisation take place in a live or post-mortem fashion? Opinions on the question abound and are divided. Dury and Santana [11] argue for live execution stating that it allows for a much greater level of interaction within the environment. Bedy et al. [12] also favour live execution. Their main argument against post-mortem lies in the need for a program to be instrumented for post-mortem analysis, as well as the risk of incomplete or corrupted data being collected as a result of an abnormal program termination. Kraemer [2] provides an interesting discussion on the subject. She states: “live execution cannot be too detailed as the viewer would find it difficult to comprehend such a rapidly updating, highly detailed display”. However, although she states that postmortem execution allows for a richer display, she also warns about the overhead that such an approach brings both in terms of processor cycles and disk space. We chose a hybrid architecture. We address the limitations pertaining to live visualisation by allowing the user to dynamically pause or slow down the execution of the program under study. Furthermore, we provide the user with the ability to rewind the execution of the program.

3.4 Display Choosing a display to illustrate concurrent object-oriented software execution is a difficult task. Kraemer [2] states that the most effective displays are those that map well to the programmer’s model of computation. We choose the UML Sequence and Statechart diagram because it naturally depicts the message passing interaction between the different objects within the executing program in a timely fashion as discussed in [10] and section 3.2 above. We present the graphical concepts of our proposed display in the next six subsections. 3.4.1 Objects Depiction of objects in Jacot is exactly as prescribed by the UML specifications [9]. Objects are represented by rectangles, with the object’s name and its unique identifier centred in the rectangle. A vertical dashed-line (commonly referred to as a lifeline) denotes that the object is alive but not currently active. When an object becomes active, as a result of one of its method being invoked or while performing some actions, the lifeline is substituted for a vertical lane (commonly referred to as an Activation diagram). As the execution of the program proceeds, the object’s lifeline or activation diagram is incremented from top to bottom. When an object ceases to exist, its lifeline or activation diagram

6

is halted and a red “X” is drawn below it. Figure 1 illustrates object creation, activation and deletion. It also depicts method invocations as well as thread interleaving and termination

Figure 1: Sequence Diagram 3.4.2 Method invocation We also make no changes to the UML specifications for method invocations. Method invocations are depicted as directed arrows from the calling objects to the called objects. In the case of a method in an object calling another method in the same object commonly referred to as a self-call, this is represented as a curved directed arrow. An example of a self-call is the “delay” method in Figure2. A synchronised method call is shown as a filled solid arrowhead, while an unsynchronised method call has a stick arrowhead. A dashed arrow with a stick arrowhead is used to illustrate a return from method call. Figure 2 illustrates the different method invocations. The first processString method is an example of an unsynchronised method call. The delay method shows a self-call, while the updated methods depict unsynchronised and return from method calls respectively.

Figure 2: Examples of method invocations 3.4.3 Thread Depiction The UML specification does not define a rich notation for threads. We define our first set of extensions to the UML to graphically depict thread activation within Jacot. In order to differentiate between the different threads executing, we

7

represent each thread in a separate colour. Furthermore, thread activation is commonly associated with message passing paradigms. Incidentally, thread creation and termination are also depicted in the Sequence view as a method invocation with a directed arrow in the colour of the thread and a wavy symbol, to indicate thread creation and with a “9” symbol to indicate thread termination. However, the current colour association of threads does not allow the tool to scale well. The next version will address this issue by associating a colour to each object. Threads created by this object will then share tones of this colour at increment of 25. This addresses several design limitations of software visualisation. Firstly, it minimises the difficulty associated with assigning a different colour to each thread. Secondly, it enables the clustering of threads created by a particular object to be made possible. 3.4.4 Thread Monitoring We believe that it is important to depict the state of the threads during execution. Therefore, we propose a Thread State Diagram, based on the UML Statechart diagram. One of our objectives is to fully utilise UML diagrams and concepts. During its lifetime, a thread can be in any of seven states, namely created, waiting, runnable, running, waiting on a monitor, sleeping and terminated. We choose, however, not to represent the created and running states because they are, essentially, conceptual states of threads in concurrency and in reality, threads only transit briefly in those two states. We instead depict an “unknown” state, primarily because the JVM supports such a state but more importantly because it depicts a thread that has been suspended by the debugger. The Thread State Diagram consists of six interconnected states, each depicting one of the above states including the “unknown” state, together with an initial pseudostate and a final transition, as prescribed by UML. The terminated state contains the threads that have ceased to be active. These threads will be depicted in this state until the program terminates. The threads are then depicted inside the states as filled circles in the thread colour. We also include a number inside each circle to indicate the thread’s priority. Furthermore we provide vital statistics about the thread by right-clicking on the circle. These threads migrate from one state diagram to the other as a result of a change in their state, as shown in Figure 3.

Figure 3: Thread State Diagram

8

3.4.5 Object Monitor UML supports the concept of active objects; that is one that holds a thread of control. An active object is portrayed by drawing the rectangle for the object with a thick border. We draw the object in the colour of the thread. However, since many threads will share the same colour with differing shades, we extend the concept by adding the thread unique identifier to the object diagram to provide more accurate depiction of the thread holding the object’s monitor. 3.4.6 Synchronisation UML defines the concept of “focus of control” but not “critical sections” specifically. We believe that it is important to show the exclusive access to critical sections of the program explicitly. We extend the UML specifications to represent synchronisation by shading the portion of the activation diagram pertaining to the critical section in the thread’s colour. Alongside the object’s monitor, graphically depicting the synchronisation of critical section should assist the user gain some proper insight into protecting the integrity of the program under study and visualising race conditions.

3.5 Visualising concurrency issues Following the discussion of the general design issues, we look at how the visualisation tool addresses the concurrency issues that were discussed in section 2. 3.5.1 Contention (Starvation) Visualising contention involves monitoring the activity of threads within the Sequence Diagram. The user may conclude that a thread is starved of CPU time by observing long periods of inactivity by the contended thread in the Sequence Diagram. However, Contention is better illustrated in the Thread State Diagram. In the case of contention due to priority, glancing at the pool of waiting and monitor threads should indicate whether the contended thread has a lower priority than other running threads. In the case of a fairness problem causing starvation, we provide useful statistics whereby the user can query the thread and obtain an estimate of the time spent in the above two states. 3.5.2 Dormancy Dormancy is illustrated by monitoring the invocation of synchronisation primitives in the Sequence Diagram together with the activity of the threads executing. This allows the developer to identify the simple case of a wait command not followed by a notification. However, it is also useful in elucidating the more complex synchronisation problem whereby a thread gets notified before the wait process has even started. The thread state diagram may not provide an explanation as to why the thread is dormant. However, it assists by showing the waiting threads and providing information regarding the time spent in that state. 3.5.3 Deadlock Deadlock is more accurately depicted in the executing program by observing the interleaving of thread invocation, for which the Sequence Diagram is particularly powerful. The occurrence of deadlock can be portrayed in the Sequence Diagram by following the offending threads along the crime trail while observing the locking sequence of objects by threads at differing times during the execution. The order of the locks sequences, the frequency of the locks, the 9

duration of the locks and the activities performed while the locks are in place provide crucial information in analysing the deadlock. The thread state diagram can shed light on the order of transition of the thread state. It can also provide clues about the time spent in different states. Combined, these two diagrams can assist in portraying the four conditions for the occurrence of deadlocks as discussed in [6] and section 2.1.

4. ARCHITECTURE OF JACOT In this section we outline the chosen platform and present an overview of the architecture of Jacot based on the design decisions discussed in the previous section. Jacot is based on a four-layer model built on top of the three-layer Java Platform Debugger Architecture (JPDA) [13] architecture as shown in Figure 4. It is modular allowing it to be extensible and accommodate for more views to be added in the future. This tool is the successor to the COOPE environment [10, 14] as our objectives have evolved. The implementation of Jacot is discussed in [1].

Figure 4: Jacot Architecture

4.1 Platform Java was chosen as the implementation platform for many reasons. Firstly Java offers platform independence. This allows us to evaluate Jacot under different operating systems. Secondly, Java uses a virtual machine. More specifically the JPDA architecture provides mechanism to significantly assist in the gathering of events from the program under study. The three layers comprising the JPDA are: ƒ

The Java Virtual Machine Debug Interface (JVMDI): a native interface that defines the debugging services that each VM must provide;

ƒ

The Java Debug Wire Protocol (JDWP): A protocol that defines the communication format between the program being debugged and the debugger and

ƒ

The Java Debug Interface (JDI): a high-level pure Java interface that defines information and requests at the user level in pure Java code.

Jacot uses the JDI to obtain traces from the program under study. The main advantage of using the JDI is that these traces can be obtained in a non-invasive manner, thus eliminating the need to modify the source code of the “debugged” software. The two benefits of this approach are that: 10

i.

It reduces the risk of inclusion of errors in the code; and

ii.

It allows for a much wider range of software to be visualised, even if the source code is unavailable.

Thirdly, Java offers a rich graphical interface inbuilt in the language, thus allowing powerful graphical user interface to be implemented without the need to import external libraries. We make use of the Swing and Java2D graphics methods in our implementation. Finally, our aim is to visualise concurrent Java programs and it seems rather logical to implement the visualisation tool using the same platform. Furthermore, this gives us the potential to visualise the inner-workings of Jacot in the future.

4.2 Event Gathering Layer The Event Gathering layer is responsible for requesting and collecting events from the “debuggee” VM. The events are gathered in a “polling” fashion. Once started, the tool waits and listens for events from the “debuggee” VM to be placed on the Event Queue. Once an event is generated, the event set is removed from the queue. The program then iterates through the set of events wrapping each event in a message that is then forwarded to the next layer for processing. These steps are repeated indefinitely until either an event notifying that the “debuggee” VM has been terminated or the program exits.

4.3 Event Processing Layer The Event Processing layer gathers detailed information about each event and encapsulates it into an object that is then sent to higher layers to be displayed. After careful considerations regarding the level of abstraction that need to be provided by the visualisation interface and taking into account the four overlapping guidelines for visualisation as discussed in [15] we arrive at the following set of desirable functionalities for Jacot. These are: (i) object creation and destruction; (ii) method invocations; (iii) thread creation, termination and status; (iv) dynamic interleaving of threads; (v) object’s monitor; (vi) exception handling and (vii) depiction of critical sections. The main function of this layer is to determine the type of the event received and querying the JDI for information about the event. For our purposes, this can be any of a Method Entry, Method Exit, VM Start, VM Death, Caught Exception, Thrown Exception or Class Prepare event. The type of the event further determines what additional information can be gathered as well as their types. For example from a Method Entry event object, we can obtain information relating to the name of the method making the call; the ID of the thread executing the method; the name and group name of the thread; the ID and name of the “calling” and “called” objects and more specific information about the method itself, such as whether it is synchronised, static, final or abstract. We identify the objects associated with an event by pairing the object’s name and object’s ID together. The object ID alone is not sufficient in the case of a static method call since the ID returned by the JDI, in this case, is undefined as this in fact refers to a call to or from a class. We cater for this by combining the object ID with the object name.

11

Furthermore in the case of method invocations, only one object is readily available in the event trace obtained from the JPDA. In the case of method entry, the object that is obtained from the JVM is the “called” object. We obtain details of the “calling” object by traversing the stack of method calls made by this thread. The call prior to the current call provides the identity of the “calling” object.

4.4 View Formatting Layer The “View Formatting” layer is mainly concerned with arranging the information passed on from the previous layer in a coherent manner on the screen. Decisions such as placement location, shape, size, colour, shade are dealt with here. The two views within Jacot handle the formatting of their respective views independently and differently.

4.5 Display Layer The Display layer comprises of a dozen classes each responsible for drawing a graphical component on the screen.

5. IMPLEMENTATION DECISIONS The Jacot visualisation tool is implemented as a stand-alone application running on the same platform as the program under study. This poses the problem of contention of memory and processor cycles between the program and Jacot. However, competing for the shared resources on the computer may bring forth hidden errors in the program that may never have been uncovered if the program was not contending for resources. We also decided to build the application from scratch rather than rely on an existing open tool that supports UML and allows the user to change the underlying UML metamodel [9]. Our decision was motivated by the fact that Jacot is a prototype and our main goal is to validate our concepts. Jacot executes by starting a new JVM to run the target program. From this point forward, Jacot controls the execution of the program. The main window provides the user with the ability to play, pause, slow down and stop the execution of the program using the “play/pause” and “stop” buttons and the slider on the menu bar. The executing program retains all of its functionalities though, opening the same windows, performing the same tasks and displaying the same information as it does when executing on its own.

6. A RUNNING EXAMPLE OF CONCURRENCY PROBLEMS To illustrate the visualisation of concurrency problems, we chose the Dining Philosophers problem, one of the classic examples in the literature used to demonstrate deadlock in a multithreaded program. The problem is as follows. Five Philosophers are seated around a table with a bowl of spaghetti in the middle and only one chopstick between each pair of Philosophers. However, because the spaghetti is long and tangled, each Philosopher needs two chopsticks to eat. A simplified version of the run method of the Philosopher class is listed below:

12

public void run() { try { while (true) { // thinking Thread.sleep(thinkingDelay); // hungry rightFork.grab(); // delay picking of left fork Thread.sleep(grabDelay); leftFork.grab(); // eating Thread.sleep(eatingDelay); // release forks rightFork.release(); leftFork.release(); } } catch (InterruptedException ie) [1] }

Table 1: The run method of the Philosopher class The grab and release methods of the Chopstick class are listed below: public synchronized void grab() throws InterruptedException { while (holder != null){ wait(); } holder = Thread.currentThread(); } public synchronized void release() { holder = null; notify(); }

Table2: The grab and release methods of the Chopstick class

13

Figure 5: Deadlock of the Dining Philosopher program depicted by the Sequence Diagram

Figure 6: Thread State Diagram depicting the Deadlock

Figure 5 and 6 show the execution of the Dining Philosophers problem using Jacot. From the view, we notice that a deadlock has occurred and execution of the program has been halted. Each philosopher has successfully acquired one chopstick and made an attempt at grabbing a second one. Philosopher 414 has grabbed Chopstick 404. Philosopher 413 has grabbed Chopstick 403. And so on. Finally, Philosopher 411 has grabbed Chopstick 401.

14

The problem arises when the philosophers attempt to grab another chopstick. Philosopher 406 attempts to grab Chopstick 404, which is currently held by Philosopher 414. Philosopher 414 attempts to grab Chopstick 403, which is held by Philosopher 413. And so on. Finally, all the objects are deadlocked because each Philosopher has grabbed one chopstick but cannot obtain another one, and yet, no one releases his chopstick. This is more accurately depicted in the Thread State Diagram where all but one threads are shown in the Waiting pane.

7. RELATED WORK Over the past years, much research has emerged in the area of software visualisation. However, only a few of these deal with concurrent object-oriented software execution. We review the more recent ones, as well as the ones dealing more closely with concurrency issues, UML and Java. JaVis [16] is a tool for visualising and debugging concurrent Java programs. The visualisation is performed using Sequence and Collaboration diagrams, based on the UML [9] paradigm. JaVis uses the UML Case Tool Together as its implementation platform. The main objective and strength of the tool is in the discovery and notification of deadlocks. The Sequence diagram shows the interleaving of method invocations between objects. JaVis implicitly supports safety issues, particularly data race conditions. The Collaboration diagram is particularly powerful at depicting the dependencies among objects executing within the program. JaVis also supports abstraction, depicting only the objects and method calls directly involved in the deadlock. JaVis shares many of its functionalities with Jacot. However, at the time of writing, unlike Jacot, JaVis only focuses only on deadlock issues. Javavis [17] is an educational visualisation tool to support the teaching of object-oriented concepts in Java to novices. The tool is quite similar to JaVis with the exception that it does not yet support concurrency concepts. Javavis also uses UML Sequence diagrams as medium for the visualisation. Despite not supporting concurrency, it shows good promise by displaying an object diagram for each active method on the call stack of threads, with interesting navigational features. Jinsight [18] can be regarded as a visual debugger for visualising the run-time performance of Java programs. It does not aim directly at addressing concurrency issues. Instead it is mainly powerful at uncovering memory leaks. One of its views, the Call Tree view, can be used to demonstrate the interleaving of events during the execution. The Histogram view depicts the usage of basic resources such as CPU and memory within the system and could potentially be used to address safety issues, such as data integrity. The Pattern reference view is particularly interesting as it provides some mechanisms for abstraction of the system. The Parade [19] environment supports components to assist in the implementation of visualisation tools. It also includes a visualisation component that monitors concurrent program execution. Parade uses the POLKA [20] animation system to implement the visualisation. The visualisation is made up of four views: the Threads view, the Function view, the History view and the Mutex view. The Threads view is similar to our Thread Status view in that it

15

shows the threads in a unique colour. However, it only depicts the status of the threads as runnable (coloured), blocked (half coloured) and terminated (black). The Function view shows the dynamic execution of the functions in the program and displaying the threads within each function as coloured circles. The History view provides a listing of the method invocations since the start of the program. It is very similar to our Sequence view but not as detailed. The Mutex view shows the current state of each mutual exclusion lock in the program. It provides the same functionality as an object’s monitor in Java.

8. CONCLUSION AND FUTURE WORK Concurrency and object-orientation are very challenging concepts for the user to grasp. This is due to a vast number of factors, which are inherent to concurrent programs, namely the inherent non-determinism of threads and multiple flow of control. Research has shown that visualisation can be of assistance in expediting the comprehension of concurrent objectoriented software execution. In this paper, we have outlined the need for a suitable environment to represent the execution of concurrent object-oriented programs in Java. We have outlined the common challenges of concurrency that novice programmers are faced with and formulated some design decisions, which in our belief form the desired characteristics of a visualisation tool. We have then proceeded to present Jacot, a tool for visualising concurrent Java programs based on the UML Sequence and Statechart diagrams paradigm. Our main focus was to provide a visual environment that captured the intricacies of concurrent programs and presented them in a simple format so as to loosen the user’s burden. Our next objective was to ensure that the event gathering process was performed in a non-invasive manner in order to avoid the inclusion of additional errors when annotating the code. Furthermore, by ensuring that the software being visualised did not need to be amended, we catered for a much wider range of software to be visualised. The first version of Jacot is complete. The next version will support other concurrency issues such as object monitors and depiction of critical sections within the program. We will also depict the progression of uncaught exceptions along the stack of calling methods within the program. Sadly, this is one feature that is missing from all visualisation environments currently in the literature. Although, we are advocates of live execution, our observations of executing multithreaded programs from within our tool show that it can have a significant impact on their threading model, especially when the visualisation is slowed down to accommodate for rapidly updating events. This is more apparent with programs having a rich graphical user interface that tend to lag behind the output of our views. Therefore, we will provide logging facilities of generated events. This should allow us to play, rewind and forward the execution of a concurrent Java program in true postmortem fashion. This is one feature that we believe should be very useful to novice programmers, especially the ability to locate which event triggered a change in the status of a thread.

16

Furthermore, we aim to propose a greyscale version of the views with the same semantics associated with colours for the interface, in a character format, which would be suitable for printing.

9. ACKNOWLEDGMENTS We would like to thank Dr Christopher Exton for his invaluable comments and support during the early stages of the research and Ms. Megan Seen for her feedback and comments on the first draft of this paper.

10. REFERENCES 1.

H. Leroux, A. Requile-Romanczuk, C. Mingins. (2003), "JACOT: A Tool to Dynamically Visualise the Execution of Concurrent Java Programs", in J. F. Power et al. (ed.), Proceedings of the Second International Conference on the Principles and Practice of Programming in Java, Kilkenny City, Ireland, Computer Science Press, ISBN: 0954414519, pp. 201-207.

2.

E. Kraemer. (1998), "Visualizing Concurrent Programs", in (ed.), vol. Software Visualization: Programming as a Multimedia Experience, MIT Press, p. 237-256.

3.

E. W. Dijkstra. (1968), "GOTO statement considered harmful", Communications of the ACM, vol. 11, no. 3, pp. 147-148.

4.

J. Williams, A. Lock, J. Crisp, A. Longstaffe. (1999), "The Use and Capture of Images for Computer-Based Learning II", Available: http://www.agocg.ac.uk/reports/graphics/capture2/capture.pdf [Accessed February 2003].

5.

D. Lea. (2000), Concurrent Programming in Java: Design Principles and Patterns. Addison-Wesley, MIT, ISBN: 0-20131009-0.

6.

E. G. Coffman, M. J. Elphick, A. Shoshani. (1971), "System deadlocks", ACM Computing Surveys, vol. 3, no. 2, pp. 67-78.

7.

Sun Microsystems. (2001), "JavaTM Standard Development Kit", Available: http://java.sun.com/j2se/1.4.1/ [Accessed February 2003].

8.

B. Lewis. (2002), "Debugging Backwards in Time", Available: http://www.lambdacs.com/debugger/USENIX/Debugger_USENIX.pdf [Accessed November 2002].

9.

OMG. (2001), "Unified Modeling Language Specification v.1.4", Available: www.omg.org [Accessed 13 May 2003]. 17

10. H. Leroux, C. Exton. (2001), "Visualising the Execution of Concurrent Object-Oriented Programs Dynamically using UML", in Proceedings of the 5th International Conference on Computer Graphics, Visualization and Computer Vision, Plzen, Czech Republic, ACM Press, ISBN: 80-7082-713-0, pp. 114-119. 11. J.-Y. Dury, M. Santana. (1994), "Virtual Images: Interactive Vizualisation of Distributed Object-Oriented Systems", in Proceedings of the 9th Annual Conference on Object-Oriented Programming Systems, Language and Applications, Portland, Oregon, USA, ACM Press, ISBN: 0362-1340, pp. 65-84. 12. M. Bedy, S. Carr, X. Huang, C.-K. Shene. (2000), "A Visualisation System for Multithreaded Programming", in Proceedings of the 31st SIGCSE Technical Symposium, Austin, Texas, ACM Press, ISBN: 0097-8418, pp. 1-5. 13. Sun Microsystems. (2001), "JavaTM Platform Debugger Architecture", Available: http://java.sun.com/products/jpda/ [Accessed February 2003]. 14. H. Leroux, C. Exton. (2001), "COOPE: A Tool for Representing Concurrent Object-Oriented Program Execution through Visualisation", in K. Klöckner (ed.), Ninth Euromicro Workshop on Parallel and Distributed Processing, Mantova, Italy, IEEE Computer Society, pp. 71-76. 15. C. Exton. (2000), "Dynamic Visualization of Concurrent Object-Oriented Systems", in C. Jesshope et al. (ed.), International Workshop on Advanced Learning Technologies (IWALT2000), Palmerston North, New Zealand, IEEE Computer Society, pp. 294-295. 16. K. Mehner. (2002), "JaVis: A UML-Based Visualization and Debugging Environment for Concurrent Java Programs", in S. Diehl (ed.), Lecture Notes in Computer Science, vol. 2269, Software Visualization: International Seminar, Springer-Verlag, Berlin, p. 163-175. 17. R. Oechsle, T. Schmitt. (2002), "JAVAVIS: Automatic Program Visualization with Object and Sequence Diagrams Using the Java Debug Interface (JDI)", in S. Diehl (ed.), Lecture Notes in Computer Science, vol. 2269, Software Visualization: International Seminar, Springer-Verlag, Berlin, p. 176-190. 18. W. D. Pauw, E. Jensen, N. Mitchell, G. Sevitsky, J. Vlissides, J. Yang. (2002), "Visualizing the Execution of Java Programs", in S. Diehl (ed.), Lecture Notes in Computer Science, vol. 2269, Software Visualization: International Seminar, Springer-Verlag, Berlin, p. 151-162.

18

19. J. T. Stasko. (1995) "The PARADE Environment for Visualizing Parallel Program Executions: A Progress Report", Technical Report, Report No.: GIT-GVU-95-03, Georgia Institute of Technology, Atlanta. 20. J. T. Stasko, E. Kraemer. (1993), "A methodology for building application-specific visualizations of parallel programs", Journal of Parallel and Distributed Computing, vol. 18, no. 2, pp. 258-264.

19

Suggest Documents