Empowering Student Debugging in Parallel Programming with Execution Traces and Large Language Models God’salvation F. Oguibe
[email protected] The University of Texas at San Antonio San Antonio, TX, USA
Vinodh Kumaran Jayakumar [email protected] The University of Texas at San Antonio San Antonio, TX, USA
arXiv:2606.14607v1 [cs.SE] 12 Jun 2026
Andrew Lan
[email protected] The University of Massachusetts Amherst Amherst, Massachusetts, USA
Abstract Concurrent programming is a core component of Computer Science curricula, yet remains notoriously difficult for students to master due to its inherent complexity and the nondeterministic nature of concurrency bugs such as deadlocks and race conditions. In this work, we present ParaView, an educational tool designed to help students understand, debug, and correct concurrency issues in parallel programs written in C/C++. ParaView provides transparent execution recording and visualization to make parallel execution observable and comprehensible. We evaluated ParaView through a series of debugging and implementation tasks, with 17 students participating. Results showed a significant improvement in debugging and implementation successes compared to previous course iterations. A student survey confirmed that most participants found ParaView helpful. To further support learning outside the classroom, we explored using Large Language Models (LLMs) to analyze concurrency bugs and suggest fixes. While LLMs were highly effective in identifying bugs and explaining execution traces, the correctness of their bug fixes varied, especially for more complex synchronization patterns. Our findings suggest that recording-visualization tools like ParaView, complemented by artificial intelligence (AI), can improve teaching and learning of concurrent programming.
CCS Concepts • Computing methodologies → Parallel computing methodologies; • Applied computing → Computer-assisted instruction.
Keywords Parallel Programming, Educational Tools, Large Language Model
1
Introduction
Since the decline of Dennard Scaling around 2005, the improvement in single-core CPU performance and clock frequency has slowed significantly. To maintain progress in overall system performance, major chip manufacturers shifted toward increasing the number of cores. Consequently, multi-core processors have become standard, and software must now be written in a concurrent or multithreaded manner to fully utilize the available hardware resources.
Tongping Liu
[email protected] The University of Massachusetts Amherst Amherst, Massachusetts, USA
Wei Wang
[email protected] The University of Texas at San Antonio San Antonio, TX, USA As a result, it is crucial for undergraduate students in Computer Science (CS) programs to develop a strong understanding of concurrent programming. Fundamental courses in these programs – such as Operating Systems, Parallel Computing, and Systems Programming – cover essential concurrency topics and techniques, including processes, threads, inter-process communication (IPC), multithreading, and synchronization. These topics also correspond to the competencies outlined in the ABET accreditation criteria [1]. To support students in grasping concurrency concepts and building practical skills in concurrent programming, they are commonly assigned multiple concurrent programming projects. However, based on our extensive experience teaching Systems Programming, Operating Systems, and Parallel Computing, we have observed that many students still struggle with concurrent programming—an issue welldocumented in existing literature [4, 5, 23, 29, 31, 35]. Students frequently introduce a range of concurrency-related bugs [37, 38] into their programs, such as race conditions, deadlocks, atomicity violations [28], and order violations [28]. As prior research has shown [5, 38], multiple factors contribute to the inherent difficulty of concurrent programming: (1) Humans are generally not naturally inclined to reason about multiple tasks executing concurrently. As a result, it is challenging for students to mentally visualize the execution flow of a parallel program without external tools or guidance. (2) Concurrency bugs are inherently difficult to reproduce due to the nondeterministic nature of thread interleavings, making debugging especially challenging. Re-running the same program may not trigger the bug again, and using a debugger like GDB [42] can alter timing behavior, potentially hiding the issue. Without a means to observe buggy execution, students often struggle to identify and understand the root causes of concurrency errors. (3) Supporting students in learning concurrency is challenging for instructors and teaching assistants, especially in large classes where it’s impractical to spend significant time debugging each student’s code. Without timely feedback and guidance, students may become frustrated and lose motivation to continue learning or to pursue careers that involve concurrent programming. To maximize learning outcomes and address the challenges above, students need effective support to independently debug and correct their parallel programs. In this paper, we present our
God’salvation F. Oguibe, Vinodh Kumaran Jayakumar, Tongping Liu, Andrew Lan, and Wei Wang
initial effort toward this goal: ParaView, a novel educational tool designed to aid the teaching and learning of concurrent programming using C/C++, with a focus on helping students understand and resolve deadlock and race-condition bugs. The core functionality of ParaView is execution recording, which captures the order of synchronization primitive invocations, such as mutex locks and barrier waits, during program execution. Each recorded event includes the details of the synchronization operation, the thread ID of the invoking thread, and a timestamp. This recorded execution trace enables students to analyze the program’s behavior without needing to re-run it or rely on traditional debuggers. The recording mechanism leverages the GNU Linker’s support for wrapper functions. Each synchronization call is redirected to a custom wrapper that logs the invocation before calling the original function (e.g., pthread_mutex_lock). This design makes the recording process fully transparent -students can write their code normally without noticing the instrumentation. As a result, ParaView can be seamlessly integrated into existing shared-memory programming assignments as a drop-in solution without major changes. Moreover, the wrapper functions introduce minimal overhead and, in practice, have no noticeable effect on the performance (and parallel behaviors) of student programs. To further support students in analyzing program behavior, ParaView includes a web-based visualization module that displays the execution timeline of each thread. This visual representation makes it significantly easier for students to understand the flow and interaction of concurrent threads. To assess the effectiveness of ParaView in improving students’ debugging skills, we designed four programming tasks. Two involved identifying and fixing deadlocks or race conditions, while the other two involved proper use of condition variables and implementing a barrier. Out of 17 students (12 undergraduates and 5 graduates), 14 (11 undergraduates and 3 graduates) successfully completed all tasks. Notably, all 17 students correctly finished the barrier implementation, which is a significant improvement compared to previous course iterations where no students managed to solve this task. A post-assignment survey completed by 13 students showed that 12 (79%) found ParaView helpful in supporting their concurrent programming. While the results indicate that ParaView’s execution recording and visualization significantly aids many students in debugging parallel programs, some students still struggle to reason about the root causes of concurrency bugs and to identify appropriate fixes on their own. To help these students learn outside the classroom, we explored using Large Language Models (LLMs) to automatically analyze parallel code and execution traces, and suggest fixes. We evaluated LLM-assisted debugging on six programs exhibiting various deadlock issues. Our initial results showed that LLMs can successfully identify the causes of deadlocks and race conditions in parallel programs. In some cases, the LLM was able to detect the issue using only the source code, while in others, execution traces were necessary for accurate diagnosis. However, the quality of the suggested bug fixes varied. While the proposed fixes often resolved the bugs, they did not always preserve the original program logic. In particular, resolving bugs involving condition
variables and atomic instructions proved more challenging. Generating correct and context-aware fixes often required carefully crafted, task-specific prompts to guide the LLM effectively. The contributions of this paper include: 1. ParaView: An Execution Recording and Visualization Tool – A lightweight, drop-in solution that simplifies the debugging of parallel programs for students, which also can be integrated with existing shared-memory programming assignments. 2. Classroom Evaluation with 17 Students – An empirical study demonstrating the effectiveness of ParaView in improving student debugging performance and highlighting strong student acceptance and engagement with the tool. 3. Exploring LLMs for Concurrency Bug Support – An initial investigation into how LLMs can assist students in reasoning about concurrency bugs and generating potential fixes, including insights into their capabilities and limitations. The rest of this paper is organized as follows: Section 2 discusses related work; Section 3 introduces the design and implementation of ParaView; Section 4 provides experimental evaluation results; Section 6 discusses limitations and future work; and Section 7 concludes the paper.
2
Related Work
Numerous visualization and simulation tools have been developed for introductory programming courses [7–11, 13–17, 19, 20, 22, 39– 41], demonstrating the benefits of visualization in programming education. However, these tools do not support concurrent programs. Games and visualizations have also been proposed for teaching concurrency concepts [2, 21, 27, 33, 44, 48, 49], particularly through classic synchronization problems like dining philosophers and readers-writers. While educational, these tools are not designed for visualizing or debugging students’ own concurrent programs. Xie et al. [46] evaluated different visualization styles for synchronization problems; although not focused on student debugging, their findings helped inform aspects of ParaView’s design. ThreadMentor introduces a custom thread synchronization library that deviates from the POSIX standard [5], whereas ParaView remains fully POSIX-compliant. Additionally, ThreadMentor does not support debugging race conditions. Other tools have focused on specific issues—Kim et al. visualized only deadlocks [26], while Kang et al. addressed race conditions [24]. In contrast, ParaView supports visualization and detection of both deadlocks and race conditions, offering broader coverage of concurrency bugs. Several tools simulate and visualize concurrent program execution. Convit offers a GUI-based simulator using execution traces [23], and ConEE extends it with a code validator for detecting race conditions and deadlocks [31]. However, both rely on a custom programming language, limiting their applicability to modern C/C++ projects. Alpaca uses a stateless model checker to diagnose failures [35], but its complexity makes it unsuitable for undergraduate education, as noted in prior studies [31]. Deadlock Empire presents code snippets that allow students to manually explore different execution paths [18]. VITTI animates
Empowering Student Debugging in Parallel Programming with Execution Traces and Large Language Models
Student Program invoke
invoke (intercepted)
Wrapper Func.
Original Sync. Func. invoke
log Time, Thread ID, Sync. func. name, Parameters
Figure 1: Intercepting and redirecting synchronization invocations with wrapper functions in ParaView.
parallel algorithms [30], but it is not intended for concurrent program development, debugging, or verification, as noted by its authors. Progvis provides visualizations using the Storm language with limited C/C++ support [43]. Furthermore, Convit, ConEE, Progvis, VITTI, and Deadlock Empire all require manual control or scheduling to identify bugs. Some tools focus on Java concurrency. Bi et al. developed a tool that replays multithreaded Java executions using AspectJ to collect data without modifying or recompiling code [4]. JThreadSpy visualizes execution traces as UML diagrams [29]. However, none of these tools support debugging or visualization for mainstream C/C++ concurrent programming projects. Several studies have investigated using large language models (LLMs) to support programming education [25, 34, 36, 45, 47], though most focus on basic programming rather than parallel programming. An exception is the work of Estévez-Ayres et al., which evaluated ChatGPT and Bard for detecting concurrency bugs using only student code. They found them inadequate for this purpose [6]. In contrast, our results show that newer LLMs perform significantly better when provided both execution traces and code. In fact execution traces are crucial for complex programs for accurate bug detection. Furthermore, we explored the use of LLMs not only for identifying concurrency bugs but also for recommending fixes.
3 Design and Implementation of ParaView 3.1 Execution Recording As previously mentioned, the core functionality of ParaView is to log invocations of synchronization functions. This is accomplished by intercepting the student program’s calls to synchronization primitives (e.g., pthread_mutex_lock). This interception mechanism is illustrated in Figure 1, where calls to original synchronization functions are redirected to wrapper functions provided by ParaView. Each wrapper logs key details of the invocation, including the timestamp, the ID of the calling thread, the name of the synchronization function, and its parameters. These parameters typically include the address of the synchronization object (e.g., the address of a Pthread mutex) and any related attributes. After logging this information, the wrapper then invokes the original function to carry out the intended synchronization. This interception is implemented using the GCC linker’s wrapper functionality, configured through customized Makefiles. Specifically, during compilation, the -Wl,–wrap option is used to redirect calls to synchronization functions to corresponding wrapper
functions. This approach makes ParaView fully transparent to the students – their code continues to call the original synchronization functions, with the redirection occurring only at link time. Additionally, this linking-based interception introduces minimal overhead, without affecting thread execution order. It’s worth noting that, in addition to static linking, interception can also be achieved using dynamic preloading via the LD_PRELOAD environment variable. This method requires no changes to the Makefile. However, we opted for static linking to avoid requiring students to set additional environment variables during program execution, keeping the experience simpler and more seamless. The function name and parameters in the log can be easily captured by inspecting the call details within the wrapper function. Timestamps are recorded using the CPU’s timestamp instruction, RDTSC. For efficiency, thread IDs are obtained at thread creation and stored in a thread-local variable for use during logging.
3.2
Visualization
Raw logs are plain text sequences that can be difficult to interpret. To address this, we provide a web-based visualization module that transforms the log data into a more intuitive tabular format, as illustrated in Figure 2. In this view, each row represents an operation performed at a specific point in time (ordered chronologically), while each column corresponds to a thread. For example, a cell containing the text "locking mutex 0x888" in row 4 (timestamp "1234") and under the column labeled "thread-5678" indicates that thread with ID 5678 locked the mutex at address 0x888 at time 1234. This visualization enables students to directly observe the execution timeline of each thread. It is provided as a web-based interface, eliminating the need for students to install any additional software on their computers.
4 Experimental Evaluation 4.1 Experiment Setup 4.1.1 Methodology. We evaluated ParaView in our Parallel Computing course, which had 17 students participated – 12 undergraduate and 5 graduate students. These students participated in two in-class programming practice sessions, which included four problems: two focused on debugging and two on implementation. At the start of the sessions, students were introduced to ParaView, including its purpose and usage. We guided them through the first debugging task using ParaView. After this initial walkthrough, the students continued independently with the remaining three exercises using ParaView to support their work. 4.1.2 Programming Problems. Listings 1 and 2 show the core code segments used in the two debugging practice exercises. Debugging Practice 1 (Listing 1) contains a deadlock caused by circular mutex waits: the function transfer_a_to_b in Thread 1 acquires lockA followed by lockB, while the function transfer_b_to_a in Thread 2 acquires the mutexes in the reverse order. This wait leads to a classic deadlock scenario. With ParaView to record and visualize the execution, students could clearly observe that the two threads were each waiting for a lock held by the other, leading to deadlock. Debugging Practice 2 (Listing 2) involves a race condition between a producer thread and two consumer threads. The producer
God’salvation F. Oguibe, Vinodh Kumaran Jayakumar, Tongping Liu, Andrew Lan, and Wei Wang
time 31256181313074 thread -1: pthread create time 31256181878872 thread -1: pthread create time 31256182069888 thread 231125: pthread started time 31256182200190 thread 231125: locking mutex 0xc108 time 31256182228602 thread 231125: mutex 0xc108 locked time 31256182378236 thread 231126: pthread started time 31256182473166 thread 231126: locking mutex 0xc148 time 31256182498060 thread 231126: mutex 0xc148 locked time 31256182248186 thread 231125: Press enter to start transferring a ==> b. time 31260302436368 thread 231125: locking mutex 0xc148 time 31256182517860 thread 231126: Press enter to start transferring b ==> a. time 31261250860810 thread 231126: locking mutex 0xc108
visualize
Figure 2: An example of the visualized execution timeline based on recorded logs based on Listing 1.
Listing 1: Debugging practice 1 (deadlock, circular wait) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
void ∗ t r a n s f e r _ a _ t o _ b ( void ∗ p ) { ... p t h r e a d _ m u t e x _ l o c k (& l oc kA ) ; a c c o u n t _ A _ b a l a n c e −= 1 0 0 ; p t h r e a d _ m u t e x _ l o c k (& l o c k B ) ; a c c o u n t _ B _ b a l a n c e += 1 0 0 ; p t h r e a d _ m u t e x _ u n l o c k (& l o c k B ) ; p t h r e a d _ m u t e x _ u n l o c k (& l oc kA ) ; ...
} void ∗ t r a n s f e r _ b _ t o _ a ( void ∗ p ) { ... p t h r e a d _ m u t e x _ l o c k (& l o c k B ) ; a c c o u n t _ B _ b a l a n c e −= 2 0 0 ;
p t h r e a d _ m u t e x _ l o c k (& l oc kA ) ; a c c o u n t _ A _ b a l a n c e += 2 0 0 ; p t h r e a d _ m u t e x _ u n l o c k (& l oc kA ) ;
}
p t h r e a d _ m u t e x _ u n l o c k (& l o c k B ) ; ...
Listing 2: Debugging practice 2 (race condition) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Correct Incorrect Debug Practice 1 (deadlock) 12/5 0/0 Debug Practice 2 (race cond) 11/5 1/0 Implement 1 (chained consumer) 11/3 1/2 Implement 2 (barrier implement) 12/5 0/0 Table 1: Number of students (undergrad/grad) correctly finished the programming practices.
int producer ( ) { ... p t h r e a d _ m u t e x _ l o c k (& mutex ) ; c o u n t += 2 ; p r i n t f ( " Two ␣ p r o d u c t ␣ p r o d u c e d \ n " ) ; p t h r e a d _ c o n d _ s i g n a l (& c o n d v a r ) ; p t h r e a d _ c o n d _ s i g n a l (& c o n d v a r ) ; p t h r e a d _ m u t e x _ u n l o c k (& mutex ) ; ... } i n t consumer ( ) { ... p t h r e a d _ m u t e x _ l o c k (& mutex ) ; p t h r e a d _ c o n d _ w a i t (& co ndv ar , &mutex ) ; count − −; p r i n t f ( " consumed ␣ one \ n " ) ;
}
p t h r e a d _ m u t e x _ u n l o c k (& mutex ) ; ...
generates two items, which the consumer threads are meant to consume, with coordination handled via a condition variable, condvar.
However, if the producer runs too quickly, its signals to the condition variable may be missed by the consumers, resulting in a race condition. By using ParaView to record and visualize the execution, students could clearly observe that the consumer threads began waiting on condvar only after the signal had already been sent, revealing the root cause of the issue. Both implementation practices build directly on Debugging Practice 2 and involve the use of condition variables. In Implementation Practice 1, students were tasked with implementing a chained producer-consumer pattern using three threads: a producer, a consumer-producer, and a final consumer. In Implementation Practice 2, students were asked to implement a barrier synchronization primitive using condition variables and mutexes. It is worth noting that we have used Implementation Practice 2 in previous offerings of the course, and in those instances, no students were able to complete the implementation independently.
4.2
Experiment Results
Table 1 summarizes the number of students who successfully completed the four programming practices using ParaView. 14 students (11 undergraduates and 3 graduates) were able to finish all tasks correctly, though some required guidance in interpreting ParaView output initially. Particularly, for the final barrier implementation task, all students completed it successfully. For comparison, in a previous offering of the course where the same barrier implementation task was assigned, none of the students completed it during class. These results indicate that ParaView has the potential to improve students’ ability to implement and debug parallel programs independently. For the cases of failed submissions, it was mostly due to student missing parts of the two classes for this experiment. Following the in-class practice sessions, we conducted a survey to gather student feedback on the usefulness and design of
Empowering Student Debugging in Parallel Programming with Execution Traces and Large Language Models
Yes No N/A Did you use ParaView? 12 1 0 Was ParaView helpful? 12 0 1 Table 2: How students responded regarding the usefulness of ParaView. 13 Students participated in this survey. "N/A" means "no applicable".
# of Responses. Not necessary, the practices are simple. 2 I don’t understand the output/visualization. 1 The extra visualization step is cumbersome. 2 I just don’t know where to start. 1 Not applicable to me. 8 Table 3: Students responses to question "if did not use or like ParaView, what are the reasons? please select all reasons."
ParaView. A total of 13 students responded. Table 2 shows their responses regarding ParaView ’s usefulness. As shown, 12 students used ParaView and reported that it was helpful. One student did not use ParaView and marked "not applicable" when asked about its helpfulness. In a later survey response, this student explained that he found the tasks simple and did not feel the need to use ParaView. Overall, the survey results further support that ParaView was effective in assisting students with parallel programming. Table 3 summarizes the student responses regarding any issues they encountered while using ParaView. This question was a "select all that apply" question, allowing students to choose multiple relevant options. As shown in the table, eight students selected "not applicable," indicating they did not experience any issues with ParaView. Two students felt that the exercises were not difficult enough to warrant using the tool. One student reported difficulty interpreting the visualization output and was unsure how to begin, due to missing the in-class walkthrough. Additionally, two students felt that the extra visualization was unnecessary. These results suggest that ParaView was generally easy to use for most students. Additionally, as expected, students with stronger programming skills were more likely to find the tool unnecessary. ParaView was not only beneficial to students—it also proved valuable to instructors. Implementing a barrier using conditional variables has consistently been a difficult task in our teaching experience. We had to provide direct coding assistance to some undergraduate students. Traditionally, we relied on verbal explanations and diagrams to help students understand and debug their code, which often failed to clearly convey the core concepts. In some cases, students’ implementations were so convoluted that even we struggled to identify the problem. With ParaView ’s visualized execution, however, it became significantly easier to pinpoint issues in student code and to clearly explain the appropriate fixes. In this way, ParaView not only supports student learning but also enhances the instructor’s ability to teach parallel programming effectively.
Listing 3: An incorrectly submission from a student for debugging practice 2 (red line indicates the bug). 1 2 3 4 5 6 7 8 9 10 11 12
i n t consumer ( ) { ... p t h r e a d _ m u t e x _ l o c k (& mutex ) ; while ( c o u n t < 2 ) { p t h r e a d _ c o n d _ w a i t (& co nd var , &mutex ) ; } count − −; p r i n t f ( " consumed ␣ one \ n " ) ;
}
5
p t h r e a d _ m u t e x _ u n l o c k (& mutex ) ; ...
Debugging Assistance with LLM
In our teaching, some students still require help interpreting visualized logs, diagnosing bugs, and determining correct fixes. To support independent learning, especially outside the classroom, we explored automated assistance using LLMs. Specifically, we conducted a preliminary evaluation of whether LLMs could analyze parallel bugs using both faulty code and execution logs. We tested three widely available LLMs: GPT-4o [32], Gemini 2.5 Flash [12], and Claude Sonnet 4 [3]. We only used the free version of these these services, so that students do not need to pay for these services if LLMs are truly employed. Table 4 summarizes the results of our preliminary LLM study. We first tested the LLMs on Debugging Practices 1 (Listing 1) and 2 (Listings 2), providing both the buggy code and execution logs. Each LLM was asked to interpret the logs and code to identify the root cause of the concurrency bugs. As shown in Table 4, all three LLMs could clearly and correctly explain the events of execution using the logs. Their explanations also correctly linked the execution events to the code provided to them and are easy to understand. Next, we asked each LLM to suggest code fixes. For Debugging Practice 1, all LLMs proposed fixes that removed the deadlock, but also mistakenly deleted user input statements, so the results were marked as “Partially” correct. For Practice 2, all LLMs provided accurate corrections. GPT-4o and Claude used pthread_cond_broadcast, while Gemini used two condition variables. It is also worth noting that GPT-4o initially returned an incorrect fix, but subsequent attempts (even from new accounts) produced correct results. The debugging practices focused on classical concurrency issues, which we may have appeared in the LLMs’ pre-training data. To further assess their capabilities, we also tested three incorrect parallel programs written by students. Listing 3 shows one such example, where a student attempted to fix Debugging Practice 2 but made a logic error. Specifically, the student incorrectly used the condition count < 2 in the while loop on line 4, when it should be count == 0. We provided these three student-written buggy programs and their corresponding execution logs to the LLMs. As shown in Table 4, all three LLMs successfully diagnosed the root causes and generated accurate corrections. Finally, we evaluated the LLMs using a more challenging race condition example, shown in Listing 4. The bug arises from lines
God’salvation F. Oguibe, Vinodh Kumaran Jayakumar, Tongping Liu, Andrew Lan, and Wei Wang
Debugging Practice 1 Debugging Practice 2 Wrong Student Code1 Wrong Student Code2 Wrong Student Code3 Complex Race Condition
GPT-4o Can Explain Trace Can Provide Fix Yes Partially Yes Yes (on 2nd try) Yes Yes Yes Yes Yes Yes Partially Partially/No
Gemini 2.5 Flash Can Explain Trace Can Provide Fix Yes Partially Yes Yes Yes Yes Yes Yes Yes Yes Yes Partially/No
Claude 4 Can Explain Trace Can Provide Fix Yes Partially Yes Yes Yes Yes Yes Yes Yes Yes Yes Partially/No
Table 4: Results of using LLM to analyze parallel execution traces and generate code fixes.
Listing 4: A barrier wait implmentation with race condition 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
typedef s t r u c t _ m y _ b a r r i e r { / ∗ max number o f t h r e a d s u s i n g t h i s b a r r i e r ∗ / i n t max_count ; / ∗ c u r r e n t number o f t h r e a d s w a i t i n g a t b a r r i e r ∗ / int cur_count ; / ∗ s e q u e n c e number o f b a r r i e r w a i t s ∗ / int seq ; } my_barrier_t ; int my_barrier_wait ( my_barrier_t ∗ b a r r i e r ) / ∗ g e t c u r r e n t s e q u e n c e number ∗ / i n t c u r _ s e q = b a r r i e r −> s e q ; / ∗ increment the counter ∗ / int old_count = __sync_fetch_and_add ( & b a r r i e r −> c u r _ c o u n t , 1 ) ; i f ( o l d _ c o u n t < ( b a r r i e r −> max_count − 1 ) ) { / ∗ w a i t i f some t h r e a d s a r e m i s s i n g ∗ / while ( c u r _ s e q == b a r r i e r −> s e q ) { } ; } else { / ∗ r e s e t t h e c o u n t e r and i n c r e m e n t s e q ∗ / b a r r i e r −> s e q + + ; p r i n t f ( " r e s e t ␣ sequence \ n " ) ; b a r r i e r −> c u r _ c o u n t = 0 ; p r i n t f ( " r e s e t ␣ count \ n " ) ; } return 0 ;
6
7 22 to 25, where the updates of seq and cur_count for the next round of barrier synchronization are not performed atomically. Specifically, after seq is incremented, another thread may enter my_barrier_wait and modify cur_count before it has been reset, leading to a race condition. This issue is subtle and harder to detect. Nevertheless, the LLMs handled it well. As shown in Table 4, both Gemini and Claude correctly identified the non-atomic resets as the root cause using both the execution traces and code. GPT-4o also recognized this problem but also mistakenly flagged the while loop on line 18 as incorrect. However, correcting the reset logic in Listing 4 is more challenging. When prompted to correct the code, all three LLMs generated fixes using Pthread mutexes and/or condition variables. While these solutions were functionally correct, they introduced unnecessary overhead for a barrier implementation. We then asked the LLMs to resolve the issue without using mutexes or condition variables. However, none of the models could produce a correct fix under this constraint, as the correction involves atomic memory access. Overall, we found that LLMs are highly effective at identifying the root causes of concurrency bugs and explaining execution logs when provided both logs and code. Their explanations are typically clear and easy to follow. However, correctly fixing complicated and nuanced bugs may still be challenging for current LLMs.
Discussion and Future Work
Recording Memory Accesses. Many race condition bugs stem from unsynchronized memory accesses to shared variables. Currently, ParaView does not support transparent logging of such accesses. Hence, students must insert explicit logging calls manually. To address this limitation, we will add support for automatic variable access tracking through a compiler plugin or runtime instrumentation. We will carefully balance runtime overhead against monitoring accuracy to ensure it remains practical for education. Supporting other Concurrency Bugs. In the future, we plan to expand ParaView to support concurrency bugs beyond deadlock and race condition, such as atomicity violation, order violations, priority inversion, and performance issues. We will also design corresponding coding exercises and conduct additional experiments. Integrating ParaView with LLM. As large language models (LLMs) show promise in supporting concurrency education, we plan to integrate ParaView with LLMs to further assist student learning beyond the classroom. In particular, further research is needed to understand how to effectively leverage LLMs alongside execution traces and visualizations to provide reliable reasoning about code and accurate bug-fixing suggestions.
Conclusion
Concurrent programming remains a challenging topic for students, often requiring significant support to master. We introduced ParaView, a tool that visualizes thread execution and synchronization, helping students better understand and debug concurrency issues. Our classroom deployment showed clear improvements in student performance, with survey responses confirming its usefulness. To further support independent learning, we explored LLMs for analyzing code and execution traces. While LLMs reliably identified bugs and interpreted logs, generating correct fixes—especially for complex synchronization—was less consistent. Still, the combination of tools like ParaView and LLM assistance shows strong potential to enhance the teaching and learning of parallel programming.
Acknowledgment This work was supported by NSF awards 2215359 and 2215193. This paper was edited with the assistance of ChatGPT to help refine the writing and enhance clarity. The content and ideas presented in this paper are entirely the authors’ own.
Empowering Student Debugging in Parallel Programming with Execution Traces and Large Language Models
References [1] ABET organization. 2021. Criteria for Accrediting Computing Programs, 2021 – 2022. "https://www.abet.org/accreditation/accreditation-criteria/criteria-foraccrediting-computing-programs-2021-2022/". [2] Joel C. Adams, Elizabeth R. Koning, and Christiaan D. Hazlett. 2019. Visualizing Classic Synchronization Problems: Dining Philosophers, Producers-Consumers, and Readers-Writers. In Proceedings of the 50th ACM Technical Symposium on Computer Science Education. [3] Anthropic. 2025. Claude Sonnet 4. "https://www.anthropic.com/claude/sonnet". [4] Yaodong Bi and John Beidler. 2007. A Visual Tool for Teaching Multithreading in Java. Journal of Computing Sciences in Colleges 22, 6 (June 2007), 156–163. [5] Steve Carr, Jean Mayo, and Ching-Kuang Shene. 2003. ThreadMentor: A Pedagogical Tool for Multithreaded Programming. Journal on Educational Resources in Computing 3, 1 (March 2003), 1–es. doi:10.1145/958795.958796 [6] Iria Estévez-Ayres, Patricia Callejo, Miguel Ángel Hombrados-Herrera, Carlos Alario-Hoyos, and Carlos Delgado Kloos. 2024. Evaluation of LLM tools for feedback generation in a course on concurrent programming. International Journal of Artificial Intelligence in Education (2024), 1–17. [7] Micael Gallego-Carrillo, Francisco Gortázar-Bellas, and J Angel VelázquezIturbide. 2004. JavaMod: An integrated Java model for Java software visualization. In Program Visualization Workshop. 102. [8] Carlisle E George. 2000. EROSI—visualising recursion and discovering new errors. ACM SIGCSE Bulletin 32, 1 (2000), 305–309. [9] Carlisle E George. 2002. Using visualization to aid program construction tasks. ACM SIGCSE Bulletin 34, 1 (2002), 191–195. [10] Paul Gestwicki and Bharat Jayaraman. 2005. Methodology and architecture of JIVE. In ACM symposium on Software visualization. 95–104. [11] Katsuhiko Gondow, Naoki Fukuyasu, and Yoshitaka Arahori. 2010. Mierucompiler: integrated visualization tool with" horizontal slicing" for educational compilers. In ACM technical symposium on Computer science education. 7–11. [12] Google. 2025. Gemini. "https://gemini.google.com/app". [13] David Gries. 2008. A principled approach to teaching OO first. In Proceedings of the 39th SIGCSE technical symposium on Computer science education. 31–35. [14] Paul Gries and David Gries. 2002. Frames and folders: A teachable memory model for Java. Journal of Computing Sciences in Colleges 17, 6 (2002), 182–196. [15] Philip J Guo. 2013. Online python tutor: embeddable web-based program visualization for cs education. In Proceeding of the 44th ACM technical symposium on Computer science education. 579–584. [16] Juha Helminen and Lauri Malmi. 2010. Jype-a program visualization and programming exercise tool for Python. In Proceedings of the 5th international symposium on Software visualization. 153–162. [17] Matthew Hertz and Maria Jump. 2013. Trace-based teaching in early programming courses. In Proceeding of the 44th ACM technical symposium on Computer science education. 561–566. [18] Petr Hudecek and Michal Pokorny. 2021. The Deadlock Empire. "https: //deadlockempire.github.io/". [19] Cornelis Huizing, Ruurd Kuiper, Christian Luijten, and Vincent Vandalon. 2012. Visualization of Object-oriented (Java) Programs.. In CSEDU (1). 65–72. [20] Christopher D Hundhausen, Sarah A Douglas, and John T Stasko. 2002. A metastudy of algorithm visualization effectiveness. Journal of Visual Languages & Computing 13, 3 (2002), 259–290. [21] Cornelia P Inggs, Taun Gadd, and Justin Giffard. 2017. Learning Concurrency Concepts while Playing Games.. In CSEDU (1). 597–602. [22] Essi Isohanni and Maria Knobelsdorf. 2011. Students’ long-term engagement with the visualization tool VIP. In Proceedings of the 11th Koli Calling International Conference on Computing Education Research. 33–38. [23] Hannu-Matti Järvinen, Mikko Tiusanen, and Antti Virtanen. 2003. Convit, a tool for learning concurrent programming. In E-Learn: World Conference on ELearning in Corporate, Government, Healthcare, and Higher Education. Association for the Advancement of Computing in Education (AACE), 2220–2223. [24] Myeong-Sin Kang, Ok-Kyoon Ha, and Yong-Kee Jun. 2014. Visualization tool for debugging data races in structured fork-join parallel programs. International Journal of Software Engineering and Its Applications 8, 4 (2014), 157–168. [25] Majeed Kazemitabaar, Runlong Ye, Xiaoning Wang, Austin Zachary Henley, Paul Denny, Michelle Craig, and Tovi Grossman. 2024. CodeAid: Evaluating a Classroom Deployment of an LLM-based Programming Assistant that Balances Student and Educator Needs. In Proceedings of the 2024 CHI Conference on Human Factors in Computing Systems. [26] Byung-Chul Kim, Sang-Woo Jun, Dae Joon Hwang, and Yong-Kee Jun. 2009. Visualizing potential deadlocks in multithreaded programs. In International Conference on Parallel Computing Technologies. Springer, 321–330. [27] Elizabeth Koning, Joel C. Adams, and Christiaan D. Hazlett. 2019. Visualizing Classic Synchronization Problems. In Proceedings of the 50th ACM Technical Symposium on Computer Science Education. [28] Shan Lu, Soyeon Park, Eunsoo Seo, and Yuanyuan Zhou. 2008. Learning from Mistakes: A Comprehensive Study on Real World Concurrency Bug Characteristics. In Proceedings of the 13th International Conference on Architectural Support
for Programming Languages and Operating Systems (Seattle, WA, USA) (ASPLOS XIII). Association for Computing Machinery, New York, NY, USA, 329–339. doi:10.1145/1346281.1346323 [29] Giovanni Malnati, Caterina Maria Cuva, and Claudia Barberis. 2008. JThreadSpy: A Tool for Improving the Effectiveness of Concurrent System Teaching and Learning. In 2008 International Conference on Computer Science and Software Engineering, Vol. 5. 549–552. doi:10.1109/CSSE.2008.11 [30] Viswanathan Manickam and Alex Aravind. 2011. If a Picture is Worth a Thousand Words, What Would an Animation Be Worth?. In Proceedings of the 16th Western Canadian Conference on Computing Education. [31] Anna Offenwanger and Yves Lucet. 2014. ConEE: An Exhaustive Testing Tool to Support Learning Concurrent Programming Synchronization Challenges. In Proceedings of the Western Canadian Conference on Computing Education (Richmond, BC, Canada) (WCCCE ’14). Article 11, 6 pages. doi:10.1145/2597959. 2597972 [32] OpenAI. 2024. GPT-4o System Card. arXiv:2410.21276 [cs.CL] https://arxiv.org/ abs/2410.21276 [33] Miroslav Popović, Klemo Vladimir, and Marin Šilić. 2018. Application of social game context to teaching mutual exclusion. Automatika: časopis za automatiku, mjerenje, elektroniku, računarstvo i komunikacije 59, 2 (2018), 208–219. [34] Nishat Raihan, Mohammed Latif Siddiq, Joanna C.S. Santos, and Marcos Zampieri. 2025. Large Language Models in Computer Science Education: A Systematic Literature Review. In Proceedings of the 56th ACM Technical Symposium on Computer Science Education V. 1. [35] Caitlin Sadowski, Thomas Ball, Judith Bishop, Sebastian Burckhardt, Ganesh Gopalakrishnan, Joseph Mayo, Madanlal Musuvathi, Shaz Qadeer, and Stephen Toub. 2011. Practical Parallel and Concurrent Programming. In Proceedings of the 42nd ACM Technical Symposium on Computer Science Education (Dallas, TX, USA) (SIGCSE ’11). 189–194. doi:10.1145/1953163.1953222 [36] Yiyin Shen, Xinyi Ai, Adalbert Gerald Soosai Raj, Rogers Jeffrey Leo John, and Meenakshi Syamkumar. 2024. Implications of ChatGPT for Data Science Education. In Proceedings of the 55th ACM Technical Symposium on Computer Science Education V. 1. [37] Chin-Kuang Shene. 1998. Multithreaded Programming in an Introduction to Operating Systems Course. In Proceedings of the Twenty-Ninth SIGCSE Technical Symposium on Computer Science Education (Atlanta, Georgia, USA) (SIGCSE ’98). Association for Computing Machinery, New York, NY, USA, 242–246. doi:10. 1145/273133.274305 [38] Ching-Kuang Shene and Steve Carr. 1998. The design of a multithreaded programming course and its accompanying software tools. The Journal of Computing in Small Colleges 14, 1 (1998), 12–24. [39] Juha Sorva. 2012. Visual program simulation in introductory programming education. Aalto University. [40] Juha Sorva, Ville Karavirta, and Lauri Malmi. 2013. A review of generic program visualization systems for introductory programming education. ACM Transactions on Computing Education (TOCE) 13, 4 (2013), 1–64. [41] Juha Sorva and Teemu Sirkiä. 2010. UUhistle: A Software Tool for Visual Program Simulation. In Proceedings of the 10th Koli Calling International Conference on Computing Education Research. [42] Richard Stallman, Roland Pesch, Stan Shebs, et al. 1988. Debugging with GDB. Free Software Foundation 675 (1988). [43] Filip Strömbäck, Linda Mannila, and Mariam Kamkar. 2021. Pilot Study of a Visualization Tool for Object Graphs and Concurrency via Shared Memory. In Proceedings of the 52nd ACM Technical Symposium on Computer Science Education. 1294–1294. [44] Josep Valls-Vargas, Jichen Zhu, and Santiago Ontañón. 2017. Graph grammarbased controllable generation of puzzles for a learning game about parallel programming. In Proceedings of the 12th International Conference on the Foundations of Digital Games. 1–10. [45] Han Wan, Hongzhen Luo, Mengying Li, and Xiaoyan Luo. 2024. Automated Program Repair for Introductory Programming Assignments. IEEE Transactions on Learning Technologies 17 (2024), 1705–1720. [46] Shaohua Xie. 2008. Evaluating and refining diagrams that support the comprehension of concurrency and synchronization. Ph. D. Dissertation. University of Georgia, Athens, GA, USA. [47] Yi-Miao Yan, Chuang-Qi Chen, Yang-Bang Hu, and Xin-Dong Ye. 2025. LLMbased collaborative programming: impact on students’ computational thinking and self-efficacy. Humanities and Social Sciences Communications 12, 1 (2025), 1–12. [48] Jichen Zhu, Katelyn Alderfer, Anushay Furqan, Jessica Nebolsky, Bruce Char, Brian Smith, Jennifer Villareale, and Santiago Ontañón. 2019. Programming in game space: how to represent parallel programming concepts in an educational game. In Proceedings of the 14th International Conference on the Foundations of Digital Games. 1–10. [49] Jichen Zhu, Katelyn Alderfer, Brian Smith, Bruce Char, and Santiago Ontañón. 2020. Understanding Learners’ Problem-Solving Strategies in Concurrent and Parallel Programming: A Game-Based Approach. arXiv:2005.04789 [cs.HC]