14 research outputs found

    Pluggable type-checking for custom type qualifiers in Java

    Get PDF
    We have created a framework for adding custom type qualifiers to the Javalanguage in a backward-compatible way. The type system designer definesthe qualifiers and creates a compiler plug-in that enforces theirsemantics. Programmers can write the type qualifiers in their programs andbe informed of errors or assured that the program is free of those errors.The system builds on existing Java tools and APIs.In order to evaluate our framework, we have written four type-checkersusing the framework: for a non-null type system that can detect andprevent null pointer errors; for an interned type system that can detectand prevent equality-checking errors; for a reference immutability typesystem, Javari, that can detect and prevent mutation errors; and for areference and object immutability type system, IGJ, that can detect andprevent even more mutation errors. We have conducted case studies usingeach checker to find real errors in existing software. These case studiesdemonstrate that the checkers and the framework are practical and useful

    Funqual: User-Defined, Statically-Checked Call Graph Constraints in C++

    Get PDF
    Static analysis tools can aid programmers by reporting potential programming mistakes prior to the execution of a program. Funqual is a static analysis tool that reads C++17 code ``in the wild\u27\u27 and checks that the function call graph follows a set of rules which can be defined by the user. This sort of analysis can help the programmer to avoid errors such as accidentally calling blocking functions in time-sensitive contexts or accidentally allocating memory in heap-sensitive environments. To accomplish this, we create a type system whereby functions can be given user-defined type qualifiers and where users can define their own restrictions on the call graph based on these type qualifiers. We demonstrate that this tool, when used with hand-crafted rules, can catch certain types of errors which commonly occur in the wild. We claim that this tool can be used in a production setting to catch certain kinds of errors in code before that code is even run

    Sound Atomicity Inference for Data-Centric Synchronization

    Full text link
    Data-Centric Concurrency Control (DCCC) shifts the reasoning about concurrency restrictions from control structures to data declaration. It is a high-level declarative approach that abstracts away from the actual concurrency control mechanism(s) in use. Despite its advantages, the practical use of DCCC is hindered by the fact that it may require many annotations and/or multiple implementations of the same method to cope with differently qualified parameters. Moreover, the existing DCCC solutions do not address the use of interfaces, precluding their use in most object-oriented programs. To overcome these limitations, in this paper we present AtomiS, a new DCCC model based on a rigorously defined type-sound programming language. Programming with AtomiS requires only (atomic)-qualifying types of parameters and return values in interface definitions, and of fields in class definitions. From this atomicity specification, a static analysis infers the atomicity constraints that are local to each method, considering valid only the method variants that are consistent with the specification, and performs code generation for all valid variants of each method. The generated code is then the target for automatic injection of concurrency control primitives, by means of the desired automatic technique and associated atomicity and deadlock-freedom guarantees, which can be plugged-into the model's pipeline. We present the foundations for the AtomiS analysis and synthesis, with formal guarantees that the generated program is well-typed and that it corresponds behaviourally to the original one. The proofs are mechanised in Coq. We also provide a Java implementation that showcases the applicability of AtomiS in real-life programs

    Inference of reference immutability in Java

    Get PDF
    Thesis (M. Eng.)--Massachusetts Institute of Technology, Dept. of Electrical Engineering and Computer Science, 2008.This electronic version was submitted by the student author. The certified thesis is available in the Institute Archives and Special Collections.Includes bibliographical references (p. 81-83).Javari is an extension of Java that supports reference immutability constraints. Programmers write Javari type qualifiers, such as the readonly type qualifier, in their programs, and the Javari typechecker detects mutation errors (incorrect side effects) or verifies their absence. While case studies have demonstrated the practicality and value of Javari, a barrier to usability remains in the development process. A Javari program will not typecheck unless all the references in the APIs of libraries it uses are annotated with Javari type qualifiers. Manually converting existing Java libraries to Javari is both tedious and error-prone; the development process requires an automated solution. This thesis presents an algorithm for statically inferring reference immutability in Javari. The flow-insensitive and context-sensitive algorithm is sound and produces a set of qualifiers that typecheck in Javari. The algorithm is precise in that it infers the most readonly qualifiers possible; adding any additional readonly qualifiers will cause the program to not typecheck. A tool, Javarifier, implements this algorithm in order to infer the Javari type qualifiers over a set of class files. Javarifier can also insert these qualifiers into the corresponding source code, if the source code is available. Javarifier automatically converts Java libraries to Javari. Additionally, Javarifier eases the task of converting legacy programs to Javari by inferring the mutability of every reference in a program. In case studies, Javarifier correctly inferred mutability over Java programs of up to 110 KLOC.by Jaime QuinonezM.Eng

    Gradual Pluggable Typing in Java

    Get PDF
    Gradual typing provides the ability to safely mix untyped or dynamically typed code with statically typed code while maintaining, within the statically typed portion, the guarantees claimed by the static typing. It is motivated by the idea that different amounts of typing are valuable at different times during a software projects development. Less typing is useful at the prototyping stage, where requirements change frequently, and rapid development is important. More typing is useful in more mature projects where maintenance, documentation, and correctness become critically important. Gradual aims to enable a project to gradually move from one side of this spectrum to the other. Pluggable typing and pluggable typing frameworks aim to allow a language to support many different type systems, that can be developed by type system designers and plugged into the existing compiler infrastructure. The Checker Framework is built on the OpenJDK➋ Java compiler, and provides a framework to develop additional type systems that can be applied to Java code. It has been tested and proven using many other type systems. However, not all code will adopt all type systems, so a developer who wishes to check their project with a given type system may still link against other components that are not checked with that type system. Additionally, a developer may wish to adopt a new type system, but be unwilling to spend the effort necessary to annotate all the existing code for the new type system. The gradual extension to the Checker Framework aims to improve type safety of partially applied Checker Framework type systems, using gradual typing techniques. A prototype was built, and the gradual nullness type system was designed to prove it. Defining the checked-unchecked boundary is crucial. Even though the use case is limited to individual files being either entirely annotated or entirely unannotated, because Java is an object-oriented language with inheritance, many different boundary conditions present themselves. This work analyses each boundary condition in detail, and presents options for runtime tests to ensure that values crossing the boundary meet the static type requirements on the other side. The nature of the tests, and the method of passing the static type to the runtime environment is discussed. This work presents the design of the prototype, implemented in the Checker Framework and OpenJDK➋. It discusses the design of the OpenJDK➋ compiler, the Checker Framework, and how they work together. It demonstrates how the abstract syntax tree can be modified in order to effect insertion of the runtime tests. It discusses the specific implementation details needed to implement each boundary condition runtime test in Java. An evaluation of the prototype is completed looking at correctness, both through a set of synthetic tests, and by inserting artificial errors into an existing real world program; performance, by running configurations of real world programs designed to model the motivating examples; and applicability, by comparing the gradual framework with other options for improving type safety in partially annotated programs. Related work on both gradual typing and pluggable typing are discussed. Final remarks and future work concludes the work

    UniFlow: A CFG-Based Framework for Pluggable Type Checking and Type Inference

    Get PDF
    A type system is a crucial component of high-level programming languages, as it enhances program correctness by ruling out certain type errors. However, the built-in type system often adheres to a specific set of rules defined by the language's specification (e.g., Java, Kotlin and C++). Pluggable type systems were then introduced as an idea to provide customizable type rules for different scenarios. Various approaches exist for implementing a pluggable type system. The Checker Framework is a well-known framework to facilitate the development of type checkers for Java. This framework enables developers to define their type rules and override the analysis logic. Additionally, Checker Framework Inference is a framework built upon the Checker Framework to provide constraint-based whole-program inference. It helps to reduce the burden of manually annotating the codebase when applying a new type system. However, the complexity of these frameworks presents a steep learning curve to type system developers. This work examines some of the critical issues encountered from our previous experience in developing these frameworks. The Checker Framework performs its analysis on two different program representations: abstract syntax tree (AST) and control flow graph (CFG). The shared responsibilities of these representations in the framework cause readability and maintainability issues for developers. Checker Framework Inference suffers not only from the same problem but also from difficulty in employing the same type rules for type checking and type inference. This is because the underlying Checker Framework assumes type rules can be checked modularly and immediately at any AST. In contrast, the type inference is not modular and generates constraints to be solved in a later stage. We propose a novel CFG-based type system framework, UniFlow, addressing the aforementioned issues by providing a unified development process for type systems supporting both type checking and type inference. It strives to resolve types and apply type rules on the program's CFGs whenever possible. This approach reduces friction in type system development, allowing developers to focus on a single flow-sensitive program representation that is simpler than ASTs. It also forces developers to express type rules as constraints, such that the same set of type rules can be implemented once, but consistently reused in type checking and type inference. Moreover, our framework supports running multiple type systems and attempts to improve error message reporting for users. We present UniFlow's architecture and explain each crucial component and functionality in detail. We discuss the advantages and limitations of our framework. Furthermore, we explore the initial implementation of the framework and outline future research directions

    Method-Specific Access Control in Java via Proxy Objects using Annotations

    Get PDF
    Partially restricting access to objects enables system designers to finely control the security of their systems. We propose a novel approach that allows granting partial access at method granularity on arbitrary objects to remote clients, using proxy objects. Our initial approach considers methods to be either safe (may be invoked by anyone) or unsafe (may be invoked only by trusted users). We next generalize this approach by supporting Role-Based Access Control (RBAC) for methods in objects. In our approach, a policy implementer annotates methods, interfaces, and classes with roles. Our system automatically creates proxy objects for each role, which contain only methods to which that role is authorized. This thesis explains the method annotation process, the semantics of annotations, how we derive proxy objects based on annotations, and how clients invoke methods via proxy objects. We present the advantages to our approach, and distinguish it from existing approaches to method-granularity access control. We provide detailed semantics of our system, in First Order Logic, to describe its operation. We have implemented our system in the Java programming language and evaluated its performance and usability. Proxy objects have minimal overhead: creation of a proxy object takes an order of magnitude less time than retrieving a reference to a remote object. Deriving the interface---a one-time cost---is on the same order as retrieval. We present empirical evidence of the effectiveness of our approach by discussing its application to software projects that range from thousands to hundreds of thousands of lines of code; even large software projects can be annotated in less than a day

    Practical pluggable types for Java

    Get PDF
    Thesis (M. Eng.)--Massachusetts Institute of Technology, Dept. of Electrical Engineering and Computer Science, 2008.This electronic version was submitted by the student author. The certified thesis is available in the Institute Archives and Special Collections.Includes bibliographical references (p. 109-115).This paper introduces the Checker Framework, which supports adding pluggable type systems to the Java language in a backward-compatible way. A type system designer defines type qualifiers and their semantics, and a compiler plug-in enforces the semantics. Programmers can write the type qualifiers in their programs and use the plug-in to detect or prevent errors. The Checker Framework is useful both to programmers who wish to write error-free code, and to type system designers who wish to evaluate and deploy their type systems. The Checker Framework includes new Java syntax for expressing type qualifiers; declarative and procedural mechanisms for writing type-checking rules; and support for flow-sensitive local type qualifier inference and for polymorphism over types and qualifiers. The Checker Framework is well-integrated with the Java language and toolset. We have evaluated the Checker Framework by writing five checkers and running them on over 600K lines of existing code. The checkers found real errors, then confirmed the absence of further errors in the fixed code. The case studies also shed light on the type systems themselves.by Matthew M. Papi.M.Eng

    A General Pluggable Type Inference Framework and its use for Data-flow Analysis

    Get PDF
    Java's pluggable type systems provide valuable compile-time guarantees, but annotating the program with pluggable types can be a significant burden on programmers. Checker Framework Inference, a framework that aims to provide a constraint-based type inference for pluggable types, can generate type constraints over the occurrence of type qualifier of expressions according to type rules. However, there is no efficient approach to solve type constraints generated by Checker Framework Inference. This thesis presents a system called Type Constraint Solver that can solve the type constraint by encoding the constraint as a Max-SAT problem and in the LogiQL language. The system takes advantage of existing Max-SAT solvers and LogicBlox to solve the corresponding forms, and gets the concrete pluggable type qualifiers for program expressions. Type Constraint Solver provides options to separate constraints into groups and solve them in parallel. It also has extendability that can be easily extended with custom encoding logic. We developed a pluggable type system called Dataflow Type System on top of Checker Framework Inference to verify the functionality of Type Constraint Solver. The type system and its inference can perform data-flow analysis by inferring all possible run-time Java types of return types, parameters, fields, and variables at compile time. We applied Checker Framework Inference to six real-world applications of up to 39kLOC with Dataflow Type System and OsTrusted Type system resulting approximately 58,000 type constraints. We used our tool to solve these type constraints and analyzed the experimentation statistics. We manually examined the inference result and found that Type Constraint Solver is able to automatically infer the expected type qualifiers for benchmarks. Inferring the largest application with fastest inference options took about 10 seconds on average, and approximately 23,000 type qualifiers were inferred. These results suggest that our system can efficiently give correct solution for type constraints
    corecore