364 research outputs found
Automatic Detection, Validation and Repair of Race Conditions in Interrupt-Driven Embedded Software
Interrupt-driven programs are widely deployed in safety-critical embedded
systems to perform hardware and resource dependent data operation tasks. The
frequent use of interrupts in these systems can cause race conditions to occur
due to interactions between application tasks and interrupt handlers (or two
interrupt handlers). Numerous program analysis and testing techniques have been
proposed to detect races in multithreaded programs. Little work, however, has
addressed race condition problems related to hardware interrupts. In this
paper, we present SDRacer, an automated framework that can detect, validate and
repair race conditions in interrupt-driven embedded software. It uses a
combination of static analysis and symbolic execution to generate input data
for exercising the potential races. It then employs virtual platforms to
dynamically validate these races by forcing the interrupts to occur at the
potential racing points. Finally, it provides repair candidates to eliminate
the detected races. We evaluate SDRacer on nine real-world embedded programs
written in C language. The results show that SDRacer can precisely detect and
successfully fix race conditions.Comment: This is a draft version of the published paper. Ke Wang provides
suggestions for improving the paper and README of the GitHub rep
Understanding Persistent-Memory Related Issues in the Linux Kernel
Persistent memory (PM) technologies have inspired a wide range of PM-based
system optimizations. However, building correct PM-based systems is difficult
due to the unique characteristics of PM hardware. To better understand the
challenges as well as the opportunities to address them, this paper presents a
comprehensive study of PM-related issues in the Linux kernel. By analyzing
1,553 PM-related kernel patches in-depth and conducting experiments on
reproducibility and tool extension, we derive multiple insights in terms of PM
patch categories, PM bug patterns, consequences, fix strategies, triggering
conditions, and remedy solutions. We hope our results could contribute to the
development of robust PM-based storage systemsComment: ACM TRANSACTIONS ON STORAGE(TOS'23
CommCSL: Proving Information Flow Security for Concurrent Programs using Abstract Commutativity
Information flow security ensures that the secret data manipulated by a
program does not influence its observable output. Proving information flow
security is especially challenging for concurrent programs, where operations on
secret data may influence the execution time of a thread and, thereby, the
interleaving between different threads. Such internal timing channels may
affect the observable outcome of a program even if an attacker does not observe
execution times. Existing verification techniques for information flow security
in concurrent programs attempt to prove that secret data does not influence the
relative timing of threads. However, these techniques are often restrictive
(for instance because they disallow branching on secret data) and make strong
assumptions about the execution platform (ignoring caching, processor
instructions with data-dependent runtime, and other common features that affect
execution time). In this paper, we present a novel verification technique for
secure information flow in concurrent programs that lifts these restrictions
and does not make any assumptions about timing behavior. The key idea is to
prove that all mutating operations performed on shared data commute, such that
different thread interleavings do not influence its final value. Crucially,
commutativity is required only for an abstraction of the shared data that
contains the information that will be leaked to a public output. Abstract
commutativity is satisfied by many more operations than standard commutativity,
which makes our technique widely applicable. We formalize our technique in
CommCSL, a relational concurrent separation logic with support for
commutativity-based reasoning, and prove its soundness in Isabelle/HOL. We
implemented CommCSL in HyperViper, an automated verifier based on the Viper
verification infrastructure, and demonstrate its ability to verify challenging
examples
Predictive Monitoring against Pattern Regular Languages
In this paper, we focus on the problem of dynamically analysing concurrent
software against high-level temporal specifications. Existing techniques for
runtime monitoring against such specifications are primarily designed for
sequential software and remain inadequate in the presence of concurrency --
violations may be observed only in intricate thread interleavings, requiring
many re-runs of the underlying software. Towards this, we study the problem of
predictive runtime monitoring, inspired by the analogous problem of predictive
data race detection studied extensively recently. The predictive runtime
monitoring question asks, given an execution , if it can be soundly
reordered to expose violations of a specification.
In this paper, we focus on specifications that are given in regular
languages. Our notion of reorderings is trace equivalence, where an execution
is considered a reordering of another if it can be obtained from the latter by
successively commuting adjacent independent actions. We first show that the
problem of predictive admits a super-linear lower bound of , where
is the number of events in the execution, and is a parameter
describing the degree of commutativity. As a result, predictive runtime
monitoring even in this setting is unlikely to be efficiently solvable.
Towards this, we identify a sub-class of regular languages, called pattern
languages (and their extension generalized pattern languages). Pattern
languages can naturally express specific ordering of some number of (labelled)
events, and have been inspired by popular empirical hypotheses, the `small bug
depth' hypothesis. More importantly, we show that for pattern (and generalized
pattern) languages, the predictive monitoring problem can be solved using a
constant-space streaming linear-time algorithm
Overcoming Memory Weakness with Unified Fairness
We consider the verification of liveness properties for concurrent programs
running on weak memory models. To that end, we identify notions of fairness
that preclude demonic non-determinism, are motivated by practical observations,
and are amenable to algorithmic techniques. We provide both logical and
stochastic definitions of our fairness notions and prove that they are
equivalent in the context of liveness verification. In particular, we show that
our fairness allows us to reduce the liveness problem (repeated control state
reachability) to the problem of simple control state reachability. We show that
this is a general phenomenon by developing a uniform framework which serves as
the formal foundation of our fairness definition and can be instantiated to a
wide landscape of memory models. These models include SC, TSO, PSO,
(Strong/Weak) Release-Acquire, Strong Coherence, FIFO-consistency, and RMO.Comment: 32 pages. To appear in Proc. 35th International Conference on
Computer Aided Verification (CAV) 202
Coarser Equivalences for Causal Concurrency
Trace theory is a principled framework for defining equivalence relations for
concurrent program runs based on a commutativity relation over the set of
atomic steps taken by individual program threads. Its simplicity, elegance, and
algorithmic efficiency makes it useful in many different contexts including
program verification and testing. We study relaxations of trace equivalence
with the goal of maintaining its algorithmic advantages.
We first prove that the largest appropriate relaxation of trace equivalence,
an equivalence relation that preserves the order of steps taken by each thread
and what write operation each read operation observes, does not yield efficient
algorithms. We prove a linear space lower bound for the problem of checking, in
a streaming setting, if two arbitrary steps of a concurrent program run are
causally concurrent (i.e. they can be reordered in an equivalent run) or
causally ordered (i.e. they always appear in the same order in all equivalent
runs). The same problem can be decided in constant space for trace equivalence.
Next, we propose a new commutativity-based notion of equivalence called grain
equivalence that is strictly more relaxed than trace equivalence, and yet
yields a constant space algorithm for the same problem. This notion of
equivalence uses commutativity of grains, which are sequences of atomic steps,
in addition to the standard commutativity from trace theory. We study the two
distinct cases when the grains are contiguous subwords of the input program run
and when they are not, formulate the precise definition of causal concurrency
in each case, and show that they can be decided in constant space, despite
being strict relaxations of the notion of causal concurrency based on trace
equivalence
Understanding and Mitigating Flaky Software Test Cases
A flaky test is a test case that can pass or fail without changes to the test case code or the code under test. They are a wide-spread problem with serious consequences for developers and researchers alike. For developers, flaky tests lead to time wasted debugging spurious failures, tempting them to ignore future failures. While unreliable, flaky tests can still indicate genuine issues in the code under test, so ignoring them can lead to bugs being missed. The non-deterministic behaviour of flaky tests is also a major snag to continuous integration, where a single flaky test can fail an entire build. For researchers, flaky tests challenge the assumption that a test failure implies a bug, an assumption that many fundamental techniques in software engineering research rely upon, including test acceleration, mutation testing, and fault localisation. Despite increasing research interest in the topic, open problems remain. In particular, there has been relatively little attention paid to the views and experiences of developers, despite a considerable body of empirical work. This is essential to guide the focus of research into areas that are most likely to be beneficial to the software engineering industry. Furthermore, previous automated techniques for detecting flaky tests are typically either based on exhaustively rerunning test cases or machine learning classifiers. The prohibitive runtime of the rerunning approach and the demonstrably poor inter-project generalisability of classifiers leaves practitioners with a stark choice when it comes to automatically detecting flaky tests. In response to these challenges, I set two high-level goals for this thesis: (1) to enhance the understanding of the manifestation, causes, and impacts of flaky tests; and (2) to develop and empirically evaluate efficient automated techniques for mitigating flaky tests. In pursuit of these goals, this thesis makes five contributions: (1) a comprehensive systematic literature review of 76 published papers; (2) a literature-guided survey of 170 professional software developers; (3) a new feature set for encoding test cases in machine learning-based flaky test detection; (4) a novel approach for reducing the time cost of rerunning-based techniques for detecting flaky tests by combining them with machine learning classifiers; and (5) an automated technique that detects and classifies existing flaky tests in a project and produces reusable project-specific machine learning classifiers able to provide fast and accurate predictions for future test cases in that project
Productive Development of Scalable Network Functions with NFork
Despite decades of research, developing correct and scalable concurrent
programs is still challenging. Network functions (NFs) are not an exception.
This paper presents NFork, a system that helps NF domain experts to
productively develop concurrent NFs by abstracting away concurrency from
developers. The key scheme behind NFork's design is to exploit NF
characteristics to overcome the limitations of prior work on concurrency
programming. Developers write NFs as sequential programs, and during runtime,
NFork performs transparent parallelization by processing packets in different
cores. Exploiting NF characteristics, NFork leverages transactional memory and
develops efficient concurrent data structures to achieve scalability and
guarantee the absence of concurrency bugs.
Since NFork manages concurrency, it further provides (i) a profiler that
reveals the root causes of scalability bottlenecks inherent to the NF's
semantics and (ii) actionable recipes for developers to mitigate these root
causes by relaxing the NF's semantics. We show that NFs developed with NFork
achieve competitive scalability with those in Cisco VPP [16], and NFork's
profiler and recipes can effectively aid developers in optimizing NF
scalability.Comment: 16 pages, 8 figure
- …