Nearly all modern processors now contain multiple cores and almost all modern computer systems contain multiple processors. Thus future software is likely to be both multithreaded (in which threads of a process communicate using shared memory) and distributed (in which processes in a system communicate using messages). Ensuring that a program works correctly under all possible scenarios is a very difficult task. Most real-world programs contain a large number of components which makes their formal verification infeasible. Effective tools for testing and debugging programs prior to their deployment are indispensable. Bugs persist even after extensive testing and debugging especially those that manifest under rare circumstances. Monitoring programs at runtime and possibly controlling their execution to avoid bad states is an important way to tolerate residual software bugs. In this project, we are working on developing a theory and algorithms for monitoring, analyzing and controlling a multithreaded distributed computation. Specifically, we are developing (i) a unifying framework for modeling synchronization in multicore distributed systems resulting from messages, locks and other synchronization primitives (e.g., wait/notify), (ii) offline and online algorithms for detecting and controlling predicates, expressed as temporal logic formulas, using slicing and other approaches, and (iii) scalable approaches for tracking dependency among events. Besides multicore computing, the work has applications in a variety of other areas including cloud computing, distributed databases, recovery, replica consistency and resource management. We are also developing educational tools that can be used in courses to enhance the learning experience of students working with multicore distributed systems.