Static deadlock detection method and device for java code and electronic equipment
By using thread context-sensitive pointer analysis and lock dependency graph detection, this method solves the problem of difficulty in tracing cross-thread lock dependencies in Java network programs, achieving highly accurate static deadlock detection, and is suitable for multi-threaded and distributed Java network programs.
Patent Information
- Application Number
- CN202511237634.3
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2025-08-29
- Publication Date
- 2025-12-16
AI Technical Summary
Existing static deadlock detection methods struggle to accurately track cross-thread lock dependencies when dealing with multi-threaded, highly asynchronous, and distributed deployment scenarios in Java network programs, resulting in low deadlock detection accuracy.
By introducing thread context-sensitive pointer analysis, intermediate representation code and control flow graphs are generated, a complete call graph is constructed, the lock acquisition order is identified, and circular dependency paths are detected through the lock dependency graph, generating a static deadlock detection report.
It improves the accuracy and comprehensiveness of deadlock detection in Java code, and can identify potential deadlock risks through static analysis. It is particularly suitable for network application scenarios with high concurrency and high asynchronous interaction.
Smart Images

Figure CN121144166A_ABST
Abstract
Description
Technical Field
[0001] This application relates to the field of software testing technology, and in particular to a method, apparatus, electronic device, and computer program product for detecting static deadlock in Java code. Background Technology
[0002] With the rapid development of computer and network communication technologies, Java-based network programs have become a core component supporting modern internet services. However, the runtime environment of Java network programs typically faces characteristics such as multithreading, high asynchronicity, resource sharing, and distributed deployment. While these characteristics improve system performance, they also significantly increase the probability of deadlocks in the code. Deadlocks can cause threads to be permanently blocked, and in severe cases, can lead to system resource exhaustion or even service interruption, becoming a critical issue affecting program stability and maintainability. Therefore, accurately detecting deadlocks in Java code is a technical problem that those skilled in the art need to consider. Summary of the Invention
[0003] In view of this, embodiments of this application provide a static deadlock detection method, apparatus, electronic device, and computer program product for Java code. By introducing thread context-sensitive pointer analysis, the accuracy of deadlock detection can be improved.
[0004] The first aspect of this application provides a static deadlock detection method for Java code, including:
[0005] Generate intermediate representation code and control flow graph of the Java code to be tested;
[0006] According to the preset pointer analysis rules, thread context-sensitive pointer analysis processing is performed on the intermediate representation code, and a complete call graph with context is constructed based on the result of the pointer analysis processing. Each edge of the call graph is labeled with thread context information.
[0007] Based on the control flow graph, the lock acquisition order in the execution path of each thread is identified according to the call graph, and a lock acquisition sequence is generated according to the lock acquisition order;
[0008] By analyzing the lock acquisition sequence, the deadlock detection result of the Java code under test can be determined.
[0009] In the technical solution of this application embodiment, firstly, intermediate representation code and a control flow graph of the Java code to be tested are generated; then, according to preset pointer analysis rules, thread context-sensitive pointer analysis processing is performed on the intermediate representation code, and a context-complete call graph is constructed based on the result of the pointer analysis processing, with each edge of the call graph labeled with thread context information; next, based on the control flow graph, the lock acquisition order in the execution path of each thread is identified according to the call graph, and a lock acquisition sequence is generated based on the lock acquisition order; finally, the deadlock detection result of the Java code to be tested is determined by analyzing the lock acquisition sequence. The above process, by performing thread context-sensitive pointer analysis on the intermediate representation code, can obtain a call graph with thread context information. Based on the control flow graph and combined with the call graph, the lock acquisition order in the execution path of each thread can be identified, and a corresponding lock acquisition sequence can be generated. By analyzing the dependencies between the lock acquisition orders in the lock acquisition sequence, it is possible to accurately distinguish whether there is a circular dependency phenomenon in the lock acquisition operations between different threads, thereby improving the accuracy of deadlock detection.
[0010] In one implementation of this application, before identifying the lock acquisition order in the execution path of each thread based on the call graph, and generating a lock acquisition sequence based on the lock acquisition order, the method further includes:
[0011] By traversing the control flow graph in reverse, selective anomaly analysis is used to identify and remove execution paths in the control flow graph that are unrelated to lock acquisition operations.
[0012] In one implementation of this application, thread context-sensitive pointer analysis processing is performed on the intermediate representation code according to preset pointer analysis rules, including:
[0013] According to pointer analysis rules, identify object references and data dependencies related to network callbacks between threads in the intermediate representation code, thereby determining thread context information.
[0014] In one implementation of this application, the deadlock detection result of the Java code under test is determined by analyzing the lock acquisition sequence, including:
[0015] Construct a lock dependency graph based on the lock acquisition sequence. The nodes in the lock dependency graph represent lock objects, and the edges in the lock dependency graph represent the dependency relationships of the lock acquisition order.
[0016] By analyzing the lock dependency graph, the deadlock detection results of the Java code under test are determined.
[0017] In one implementation of this application, the deadlock detection result of the Java code under test is determined by analyzing the lock dependency graph, including:
[0018] The graph cycle detection algorithm is used to detect whether there are circular dependency paths in the lock dependency graph.
[0019] If a circular dependency path exists in the lock dependency graph, then the Java code under test is suspected of having a deadlock.
[0020] In one implementation of this application, after determining that the Java code under test has a potential deadlock, the method further includes:
[0021] Based on relevant information about potential deadlocks and the lock dependency graph, generate a static deadlock detection report;
[0022] Output a static deadlock detection report.
[0023] In one implementation of this application, generating intermediate representation code and control flow graph of the Java code to be tested includes:
[0024] Lexical analysis, syntax analysis, and semantic analysis are performed sequentially on the Java code under test to generate an abstract syntax tree;
[0025] The abstract syntax tree is analyzed using a syntax tree parser to extract thread creation points, variable definitions, inheritance relationships, and function call constraints from the Java code under test, in order to generate intermediate representation code and control flow graphs.
[0026] A second aspect of this application provides a static deadlock detection device for Java code, comprising:
[0027] The basic data generation module is used to generate intermediate representation code and control flow graph of the Java code under test;
[0028] The pointer analysis module is used to perform thread context-sensitive pointer analysis on the intermediate representation code according to preset pointer analysis rules, and to construct a complete call graph based on the results of the pointer analysis. Each edge of the call graph is labeled with thread context information.
[0029] The lock acquisition sequence generation module is used to identify the lock acquisition order in the execution path of each thread based on the control flow graph and the call graph, and generate a lock acquisition sequence based on the lock acquisition order;
[0030] The deadlock detection module is used to determine the deadlock detection result of the Java code under test by analyzing the lock acquisition sequence.
[0031] A third aspect of this application provides an electronic device, including a memory, a processor, and a computer program stored in the memory and executable on the processor. When the processor executes the computer program, it implements a static deadlock detection method for Java code as provided in the first aspect of this application.
[0032] A fourth aspect of this application provides a computer program product that, when run on an electronic device, causes the electronic device to execute a static deadlock detection method using Java code as provided in the first aspect of this application.
[0033] A fifth aspect of this application provides a computer-readable storage medium storing a computer program that, when executed by a processor, implements a static deadlock detection method using Java code as provided in the first aspect of this application.
[0034] It is understood that the beneficial effects of the second to fifth aspects mentioned above can be found in the relevant descriptions in the first aspect mentioned above, and will not be repeated here. Attached Figure Description
[0035] Figure 1 This is a flowchart of a static deadlock detection method for Java code provided in an embodiment of this application;
[0036] Figure 2 This is a schematic diagram of a basic pointer analysis rule provided in an embodiment of this application;
[0037] Figure 3 This is a schematic diagram of an extended pointer analysis rule provided in an embodiment of this application;
[0038] Figure 4 This is a schematic diagram of the operation flow of the static deadlock detection method of Java code provided in the embodiments of this application in a real application scenario;
[0039] Figure 5 This is a schematic diagram of the structure of a static deadlock detection device for Java code provided in an embodiment of this application;
[0040] Figure 6 This is a schematic diagram of an electronic device provided in an embodiment of this application. Detailed Implementation
[0041] In the following description, specific details such as particular system architectures and techniques are set forth for illustrative purposes and not for limitation, in order to provide a thorough understanding of the embodiments of this application. However, those skilled in the art will understand that this application can also be implemented in other embodiments without these specific details. In other instances, detailed descriptions of well-known systems, apparatuses, circuits, and methods have been omitted so as not to obscure the description of this application with unnecessary detail. Furthermore, in the description of this application and the appended claims, the terms "first," "second," "third," etc., are used only for distinguishing descriptions and should not be construed as indicating or implying relative importance.
[0042] In mainstream Java network programs, deadlock failures account for a high proportion of all concurrency errors. Deadlocks arise from the temporal dependencies of thread contention for lock resources and are typically triggered only under specific thread scheduling conditions. Traditional static deadlock detection methods identify lock operations by analyzing code execution paths. However, when dealing with complex scenarios such as network callbacks and thread context switching, the lack of precise modeling of thread execution paths makes it difficult to accurately trace cross-thread lock dependencies, resulting in low accuracy in deadlock detection.
[0043] To address the aforementioned technical problems in the prior art, this application provides a method, apparatus, electronic device, and computer program product for static deadlock detection in Java code. By introducing thread context-sensitive pointer analysis, the accuracy of deadlock detection can be improved. For more specific technical implementation details of the embodiments of this application, please refer to the various method embodiments described below.
[0044] It should be understood that the implementing entity of the various method embodiments proposed in this application can be various types of electronic devices, such as mobile phones, tablets, desktop computers, wearable devices, augmented reality (AR) / virtual reality (VR) devices, laptops, ultra-mobile personal computers (UMPCs), netbooks, personal digital assistants (PDAs), large-screen TVs, etc. This application does not impose any limitation on the specific type of electronic device. For example, if applied in a blockchain technology scenario, the electronic device can be any blockchain node.
[0045] Please see Figure 1 This application illustrates a static deadlock detection method for Java code provided in an embodiment, comprising:
[0046] 101. Generate intermediate representation code and control flow graph of the Java code to be tested;
[0047] First, obtain the Java code to be tested. This can be any Java code that needs to perform static deadlock detection, such as the source code of a Java network program. By analyzing and preprocessing the Java code under test, corresponding intermediate representation (IR) code and control flow graphs can be generated. The intermediate representation code refers to the intermediate form of the source code converted into target code during compilation. The control flow graph (CFG) is an abstract data structure used to represent the execution path of a program or process, displaying all possible execution paths through nodes and edges, and providing a complete description of the execution path of each thread.
[0048] In one implementation of this application, generating intermediate representation code and control flow graph of the Java code to be tested includes:
[0049] (1) Perform lexical analysis, syntax analysis and semantic analysis on the Java code to be tested in sequence to generate an abstract syntax tree;
[0050] (2) Use a syntax tree parser to analyze the abstract syntax tree and extract the thread creation point, variable definition, inheritance relationship and function call constraint information of the Java code under test in order to generate intermediate representation code and control flow graph.
[0051] By sequentially performing lexical analysis, syntax analysis, and semantic analysis on the Java code under test, a corresponding Extended Abstract Syntax Tree (AST) can be generated. AST is a tree-like data structure used to represent the structure of program source code. Lexical analysis is the process of converting a sequence of code characters into a sequence of tokens, used to identify keywords, operators, and identifiers in the code, providing the basic data structure for subsequent syntax analysis. Syntax analysis is the process of converting the token sequence into an AST according to grammatical rules, used to construct a hierarchical structural model of the code. Semantic analysis is the process of checking variable types, scopes, and semantic rules to ensure the semantic correctness of the code.
[0052] After generating the abstract syntax tree (BST), a syntax tree parser can be used to analyze it, extracting information such as thread creation points, variable definitions, inheritance relationships, and function call constraints from the Java code. This generates intermediate representation code and a control flow graph, serving as the basic input data for static analysis. The syntax tree parser is a tool used to traverse and parse the BST, extracting thread creation point information to identify multi-threaded execution paths. Variable definitions refer to the declaration and initialization locations of lock objects in the code, which can be obtained by analyzing field declaration statements, used to determine the lifecycle and scope of lock objects. Inheritance relationship information refers to the parent-child hierarchy between classes, which can be obtained by analyzing keywords such as `extends` and `implements`, used to track potential parent class dependencies of lock objects. Function call constraint information refers to the context conditions and parameter types of method calls, which can be obtained by analyzing method signatures and call statements, used to construct an accurate call relationship graph.
[0053] Specifically, by deeply parsing the abstract syntax tree, thread creation points can be identified to pinpoint the starting point of concurrent execution, such as determining the thread entry point by detecting calls to the `Thread.start()` method. Variable definition information is extracted to clarify the declaration location of lock objects, such as identifying variables modified by the `synchronized` keyword or explicit lock object declarations. Inheritance relationship analysis, by traversing the class hierarchy, determines the parent class methods or fields that the lock object may inherit, avoiding omissions of dependencies due to unidentified parent class locks. Function call constraint information, by parsing method parameter types and calling context, such as identifying lock object parameters passed in different threads, ensures the accuracy of subsequent call graph construction. Existing technologies typically ignore thread creation points and inheritance relationships when generating intermediate representation code, resulting in incomplete lock object tracing in multi-threaded scenarios. Moreover, the extraction of function call constraint information is limited to local variable analysis and cannot handle cross-method lock passing scenarios. This application's embodiments, by comprehensively extracting thread creation points, variable definitions, inheritance relationships, and function call constraint information, can accurately identify distributed lock objects and cross-class dependencies, thereby improving the reliability of subsequent lock acquisition sequence analysis.
[0054] 102. According to the preset pointer analysis rules, perform thread context-sensitive pointer analysis on the intermediate representation code, and construct a complete call graph based on the result of the pointer analysis. Each edge of the call graph is labeled with thread context information.
[0055] After generating intermediate representation code and control flow graphs of the Java code under test, thread-context-sensitive pointer analysis is performed on the intermediate representation code according to preset pointer analysis rules. Based on the results of this pointer analysis, a context-complete call graph is constructed. Thread-context-sensitive pointer analysis involves tracing object references by combining thread creation points and call stack information. This can be implemented using a clone-based context modeling method to distinguish access paths to the same object from different threads. The context-complete call graph is a cross-method call relationship graph containing thread identifiers. Specifically, the caller thread context is recorded during pointer analysis to represent dynamic call chains in a multi-threaded environment. This call graph is a directed graph where nodes represent methods or functions, edges represent call relationships, and each edge is labeled with corresponding thread context information. In subsequent operations, this call graph... Figure 1 It can be used to determine the reachable path of lock acquisition operations and to track lock dependencies across methods, thereby effectively improving the comprehensiveness and accuracy of deadlock detection.
[0056] In one implementation of this application, thread context-sensitive pointer analysis processing is performed on the intermediate representation code according to preset pointer analysis rules, including:
[0057] According to pointer analysis rules, identify object references and data dependencies related to network callbacks between threads in the intermediate representation code, thereby determining thread context information.
[0058] Specifically, during pointer analysis, predefined pointer analysis rules can be used to identify object references and data dependencies related to network callbacks between threads in the intermediate representation code, thereby determining thread context information and constructing an accurate and context-complete call graph. Among these, object references related to network callbacks refer to cross-thread object access relationships triggered by asynchronous network events. This can be achieved by parsing the parameter passing paths in I / O event handlers. This feature can pinpoint implicit object sharing behavior caused by network programming patterns, providing a data foundation for lock contention analysis. In the multi-threaded environment of Java network programs, asynchronous I / O operations trigger callback functions to switch execution between different threads. By parsing the intermediate representation code layer by layer using predefined pointer analysis rules, object reference chains driven by network events can be identified. Simultaneously, when analyzing data dependencies, the focus can be on detecting lock acquisition operation sequences indirectly associated through shared buffers or message queues. For example, a producer thread acquires a write lock when writing data to a queue, and a consumer thread acquires a read lock when reading, forming a cross-thread lock dependency chain. This targeted analysis can accurately construct a thread context model containing network interaction characteristics, providing accurate cross-thread dependency data for subsequent lock sequence analysis.
[0059] As an example, Figure 2 This is a schematic diagram illustrating a basic pointer analysis rule provided in an embodiment of this application. Figure 2 The pointer analysis rules shown mainly target statements in the intermediate representation code that involve ordinary object creation, copying, field storage, field reading, array storage, array reading, and ordinary method calls, and identify the corresponding thread context information. Figure 3 This is a schematic diagram of an extended pointer analysis rule provided in an embodiment of this application. Figure 3 The pointer analysis rules shown mainly target statements in the intermediate code that involve thread object creation, thread startup calls, and callback method calls, and perform pointer analysis to identify the corresponding thread context information.
[0060] In summary, the embodiments of this application introduce a thread context modeling mechanism to identify and separate the context of thread pool task submission, callback registration, and Runnable / Callable objects. It adopts an extended rule pointer analysis algorithm to identify the reference relationships, aliases, and network I / O-related dependencies between objects, thereby constructing a complete call graph and improving the coverage integrity of lock operation paths.
[0061] 103. Based on the control flow graph, identify the lock acquisition order in the execution path of each thread according to the call graph, and generate a lock acquisition sequence according to the lock acquisition order;
[0062] After constructing a complete call graph, based on the control flow graph, the lock acquisition order in the execution path of each thread is identified. A corresponding lock acquisition sequence is then generated based on this identified lock acquisition order. This lock acquisition sequence refers to the lock operation records arranged in execution order, specifically generated by extracting the `synchronized` keyword or `Lock` object calls by traversing the control flow graph. It describes the timing of thread occupancy of lock resources. This process, by tracing lock operation nodes in the thread execution path, generates a lock acquisition sequence that reflects the actual execution logic.
[0063] Considering that the control flow graph may contain a large number of abnormal execution paths that are unrelated to lock acquisition operations, in order to improve processing efficiency and reduce the risk of false alarms, abnormal path pruning can be performed on the control flow graph first. The specific pruning method is described below.
[0064] In one implementation of this application, before identifying the lock acquisition order in the execution path of each thread based on the call graph, and generating a lock acquisition sequence based on the lock acquisition order, the method further includes:
[0065] By traversing the control flow graph in reverse, selective anomaly analysis is used to identify and remove execution paths in the control flow graph that are unrelated to lock acquisition operations.
[0066] The technical solution of this application embodiment can employ a lightweight reverse data flow analysis strategy. Starting from the lock operation point, it traverses the control flow graph in reverse. Through selective anomaly analysis, it identifies and deletes execution paths in the control flow graph that are unrelated to the lock acquisition operation, retaining only the execution paths related to the lock acquisition operation. This results in a refined control flow graph, reducing analysis complexity and the risk of false alarms. Reverse traversal of the control flow graph refers to traversing the nodes of the control flow graph from the program termination node towards the entry node. Specifically, a depth-first search algorithm can be used. This traversal method can effectively locate critical paths that may lead to the lock operation during actual execution. Selective anomaly analysis verifies the validity of code branches that may trigger uncaught exceptions. Specifically, it can identify unreachable paths by establishing an exception propagation model, eliminate invalid lock operation paths caused by program interruptions, and prune code branches in the control flow graph that do not contain synchronization blocks or explicit lock operations.
[0067] Specifically, the reverse traversal process starts from the program exit node and traces the execution path backward. Combined with selective anomaly analysis, reachability verification is performed on code branches that may cause abnormal interruptions. Then, a path pruning algorithm is used to remove code branches that do not contain lock acquisition operations and are marked as unreachable from the control flow graph. This combined approach ensures that subsequent lock acquisition sequence analysis only targets the code execution paths that are actually likely to be executed and involve lock operations, avoiding resource waste and the risk of misjudgment caused by analyzing invalid paths.
[0068] For the refined control flow graph, a branch-sensitive lock acquisition analysis algorithm can be used. This algorithm, combined with thread context information in the call graph, identifies implicit lock propagation paths in cross-thread method calls, ultimately identifying the lock acquisition order in each thread's execution path. Then, a function summary and path merging strategy is employed to extract and summarize the corresponding lock acquisition sequences. The obtained lock acquisition sequences are represented as an ordered list; for example, lockA->lockB->lockC indicates that locks A, B, and C are acquired sequentially on a certain execution path. Finally, the algorithm returns a set of all possible lock acquisition sequences. This embodiment of the application, by jointly analyzing the control flow graph and call graph, can identify implicit lock acquisition behavior passed through method parameters and distinguish lock acquisition operations executed by different threads, thereby improving the completeness and accuracy of the obtained lock acquisition sequences. This helps improve the accuracy of deadlock detection.
[0069] 104. By analyzing the lock acquisition sequence, determine the deadlock detection result of the Java code under test.
[0070] After generating all lock acquisition sequences in the manner described above, by analyzing the dependencies between the lock acquisition orders in these sequences, it is possible to accurately distinguish whether there is a circular dependency in lock acquisition operations between different threads, thereby determining the deadlock detection result of the Java code under test. The following details how to analyze the lock acquisition sequences.
[0071] In one implementation of this application, the deadlock detection result of the Java code under test is determined by analyzing the lock acquisition sequence, including:
[0072] (1) Construct a lock dependency graph based on the lock acquisition sequence. The nodes of the lock dependency graph represent lock objects, and the edges of the lock dependency graph represent the dependency relationship of the lock acquisition order.
[0073] (2) By analyzing the lock dependency graph, the deadlock detection results of the Java code under test are determined.
[0074] Based on the generated lock acquisition sequence, a corresponding Lock Dependency Graph (LDG) can be constructed. A lock dependency graph is a data model that abstracts the lock acquisition order in a multi-threaded environment into a graph structure. It can be implemented using an adjacency list or adjacency matrix and is used to visually represent the dependencies between different lock objects. Nodes in the lock dependency graph represent lock objects, and edges represent the dependencies in the lock acquisition order. These edges are generated by traversing the lock operation sequence in the thread execution path and are used to characterize cross-thread lock acquisition order constraints. For example, suppose thread 1 attempts to acquire lock Y while holding lock X. Lock X and lock Y are two different nodes in the lock dependency graph, and a directed edge from lock X to lock Y needs to be established. By analyzing whether there are cyclic dependency paths in the lock dependency graph, the deadlock detection result of the Java code under test can be determined.
[0075] Specifically, the lock dependency graph construction process first extracts the lock acquisition order in the execution paths of each thread. For example, if thread 1's lock acquisition sequence is lockA->lockB, and thread 2's lock acquisition sequence is lockB->lockA, then based on the cross-thread lock acquisition order, edges are established in the lock dependency graph from node lock A to node lock B, and from node lock B to node lock A, forming a circular dependency relationship. Subsequently, graph theory algorithms can be used to detect whether a circular dependency path exists in the lock dependency graph. For example, a depth-first search algorithm can be used to traverse all nodes, and when a node is found to have a back edge, a circular dependency path is determined to exist. This process transforms dynamic lock contention behavior into static graph structure analysis, avoiding the reliance on runtime state tracking in traditional methods.
[0076] In one implementation of this application, the deadlock detection result of the Java code under test is determined by analyzing the lock dependency graph, including:
[0077] (1) Detect whether there are circular dependency paths in the lock dependency graph using the graph cycle detection algorithm;
[0078] (2) If there is a circular dependency path in the lock dependency graph, then the Java code under test is determined to have a potential deadlock.
[0079] When analyzing lock dependency graphs, a graph cycle detection algorithm can be used. This algorithm, based on graph theory principles, detects the existence of cycles in a directed graph. Specifically, it can be implemented using a depth-first search algorithm or a topological sorting algorithm. By traversing the nodes and edges of the lock dependency graph, it determines whether a closed loop structure exists, thus identifying all circular dependency paths. A circular dependency path is a circular path composed of multiple lock objects and their dependencies. Specifically, it manifests as a scenario where thread 1 holds lock X and waits for lock Y, while thread 2 holds lock Y and waits for lock X, a mutual waiting scenario. Such paths can be identified by analyzing the pointing relationships of edges in the lock dependency graph. Each circular dependency path in the lock dependency graph corresponds to a potential deadlock. That is, if there is no circular dependency path in the lock dependency graph, the deadlock detection result is determined to be no deadlock; if there is one circular dependency path, the deadlock detection result is determined to be one potential deadlock; if there are two circular dependency paths, the deadlock detection result is determined to be two potential deadlocks, and so on.
[0080] Traditional static deadlock detection methods are typically based on linear analysis of lock acquisition order or matching of preset rules, which struggle to accurately identify circular wait problems caused by complex dependencies in multi-threaded environments. This application's embodiments introduce a loop detection mechanism from graph theory, abstracting lock dependencies into a directed graph structure and automatically identifying circular dependency paths using an algorithm, effectively avoiding misjudgments or omissions caused by incomplete manual rule coverage.
[0081] Each time a circular dependency path is detected in the lock dependency graph, it can be marked as a potential deadlock. Information such as the lock object identifier, thread identifier, lock acquisition path, and source code location involved in the potential deadlock can be recorded. This information can serve as the basis for a static deadlock detection report. If no circular dependency path is found after traversing the entire lock dependency graph, it can be determined that the Java code under test has passed verification and there is no deadlock issue.
[0082] In one implementation of this application, after determining that the Java code under test has a potential deadlock, the method further includes:
[0083] (1) Generate a static deadlock detection report based on relevant information about potential deadlocks and the lock dependency graph;
[0084] (2) Output static deadlock detection report.
[0085] Information related to potential deadlocks can be used to pinpoint the specific code segment causing the deadlock, while a lock dependency graph can be used to visualize lock contention relationships. Based on this information and the lock dependency graph, a structured document can be generated as a static deadlock detection report to assist developers in locating and fixing deadlock issues. Specifically, data can be encapsulated in formats such as XML or JSON to form the static deadlock detection report, which can then be output through a visual interface, providing traceability for deadlock analysis results. This static deadlock detection report supports graphical display of the lock dependency structure and can be embedded in a development integration environment to aid in debugging.
[0086] In the technical solution of this application embodiment, firstly, intermediate representation code and a control flow graph of the Java code to be tested are generated; then, according to preset pointer analysis rules, thread context-sensitive pointer analysis processing is performed on the intermediate representation code, and a context-complete call graph is constructed based on the result of the pointer analysis processing, with each edge of the call graph labeled with thread context information; next, based on the control flow graph, the lock acquisition order in the execution path of each thread is identified according to the call graph, and a lock acquisition sequence is generated based on the lock acquisition order; finally, the deadlock detection result of the Java code to be tested is determined by analyzing the lock acquisition sequence. The above process, by performing thread context-sensitive pointer analysis on the intermediate representation code, can obtain a call graph with thread context information. Based on the control flow graph and combined with the call graph, the lock acquisition order in the execution path of each thread can be identified, and a corresponding lock acquisition sequence can be generated. By analyzing the dependencies between the lock acquisition orders in the lock acquisition sequence, it is possible to accurately distinguish whether there is a circular dependency phenomenon in the lock acquisition operations between different threads, thereby improving the accuracy of deadlock detection.
[0087] As an example, Figure 4 This is a schematic diagram illustrating the operation flow of the static deadlock detection method for Java code provided in this application embodiment in a practical application scenario. Figure 4First, the source code of the Java network program is obtained. The Java compilation analysis module parses the source code to generate corresponding intermediate representation code and a control flow graph. Then, the extended pointer analysis module performs thread context-sensitive extended pointer analysis on the intermediate representation code, constructing a context-complete call graph based on pointer relationships. Next, the selective exception analysis module prunes the control flow graph, identifying and deleting execution paths unrelated to lock acquisition operations, thus obtaining a refined control flow graph. Then, the lock acquisition order analysis module, based on the refined control flow graph and the call graph, identifies lock acquisition order constraints and generates corresponding lock acquisition sequences. Finally, the deadlock detection module constructs a lock dependency graph based on the lock acquisition sequences, analyzes circular dependency paths in the lock dependency graph to determine if potential deadlocks exist, and outputs a corresponding static deadlock detection report. In a typical application scenario, a Java network service program has two threads that acquire lock X and lock Y respectively, and subsequently attempt to acquire the lock already held by the other, forming a lock dependency cycle. After performing static analysis using the method provided in this application embodiment, the implicit lock sequence conflict can be accurately identified, and the detection report can indicate information such as the thread path, lock variables, and source code location involved, thereby preventing the risk of deadlock before the program runs.
[0088] In summary, the embodiments of this application provide a static deadlock detection method for Java network programs. This method combines key technologies such as thread context identification, pointer analysis, abnormal path pruning, branch-sensitive lock sequence extraction, and lock dependency graph detection. It can accurately identify potential deadlock risks without running the program statically, and is particularly suitable for high-concurrency and high-asynchronous interaction network application scenarios.
[0089] It should be understood that the sequence number of each step in the above embodiments does not imply the order of execution. The execution order of each process should be determined by its function and internal logic, and should not constitute any limitation on the implementation process of the embodiments of this application.
[0090] The above mainly describes a static deadlock detection method for Java code. The following will describe a static deadlock detection device for Java code.
[0091] Please see Figure 5 This application illustrates a static deadlock detection device for Java code provided in an embodiment, comprising:
[0092] The basic data generation module 501 is used to generate intermediate representation code and control flow graph of the Java code to be tested;
[0093] The pointer analysis module 502 is used to perform thread context-sensitive pointer analysis processing on the intermediate representation code according to the preset pointer analysis rules, and to construct a context-complete call graph based on the result of the pointer analysis processing, with each edge of the call graph labeled with thread context information;
[0094] The lock acquisition sequence generation module 503 is used to identify the lock acquisition order in the execution path of each thread based on the call graph, and generate a lock acquisition sequence according to the lock acquisition order;
[0095] The deadlock detection module 504 is used to determine the deadlock detection result of the Java code under test by analyzing the lock acquisition sequence.
[0096] In one implementation of this application, the static deadlock detection device for Java code further includes:
[0097] The selective anomaly analysis module is used to reverse traverse the control flow graph and identify and delete execution paths in the control flow graph that are unrelated to lock acquisition operations through selective anomaly analysis.
[0098] In one implementation of this application, the pointer analysis module includes:
[0099] The information identification unit is used to identify object references and data dependencies related to network callbacks between threads in the intermediate representation code according to pointer analysis rules, thereby determining thread context information.
[0100] In one implementation of this application, the deadlock detection module includes:
[0101] The lock dependency graph construction unit is used to construct a lock dependency graph based on the lock acquisition sequence. The nodes of the lock dependency graph represent lock objects, and the edges of the lock dependency graph represent the dependency relationship of the lock acquisition order.
[0102] The lock dependency graph analysis unit is used to determine the deadlock detection results of the Java code under test by analyzing the lock dependency graph.
[0103] In one implementation of this application, the lock dependency graph analysis unit includes:
[0104] The circular dependency detection subunit is used to detect whether there are circular dependency paths in the lock dependency graph using a graph cycle detection algorithm.
[0105] The deadlock determination subunit is used to determine if there is a potential deadlock in the Java code under test if there is a circular dependency path in the lock dependency graph.
[0106] In one implementation of this application, the deadlock detection module further includes:
[0107] The report generation unit is used to generate a static deadlock detection report based on relevant information about potential deadlocks and the lock dependency graph;
[0108] The report output unit is used to output a static deadlock detection report.
[0109] In one implementation of this application, the basic data generation module includes:
[0110] Abstract syntax tree generation unit is used to sequentially perform lexical analysis, syntax analysis and semantic analysis on the Java code under test to generate an abstract syntax tree;
[0111] The Abstract Syntax Tree Analysis Unit (ABSA) is used to analyze the abstract syntax tree using a syntax tree parser, extracting thread creation points, variable definitions, inheritance relationships, and function call constraints from the Java code under test, in order to generate intermediate representation code and control flow graphs.
[0112] This application also provides a computer-readable storage medium storing a computer program that, when executed by a processor, implements the static deadlock detection method of Java code described in any of the above embodiments.
[0113] This application also provides a computer program product that, when run on an electronic device, causes the electronic device to execute a static deadlock detection method using Java code as described in any of the above embodiments.
[0114] Figure 6 This is a schematic diagram of an electronic device provided in an embodiment of this application. Figure 6 As shown, the electronic device 6 of this embodiment includes: a processor 60, a memory 61, and a computer program 62 stored in the memory 61 and executable on the processor 60. When the processor 60 executes the computer program 62, it implements the steps of the embodiments of the static deadlock detection methods for the various Java codes described above, for example... Figure 1 Steps 101-104 are shown. Alternatively, when the processor 60 executes the computer program 62, it implements the functions of each module / unit in the above-described device embodiments, for example, implementing... Figure 5 The functions of modules 501-504 of the device shown.
[0115] The computer program 62 can be divided into one or more modules / units, which are stored in the memory 61 and executed by the processor 60 to complete this application. The one or more modules / units can be a series of computer program instruction segments capable of performing a specific function, which describe the execution process of the computer program 62 in the electronic device 6.
[0116] The processor 60 may be a Central Processing Unit (CPU), or other general-purpose processors, digital signal processors (DSPs), application-specific integrated circuits (ASICs), field-programmable gate arrays (FPGAs), or other programmable logic devices, discrete gate or transistor logic devices, discrete hardware components, etc. A general-purpose processor may be a microprocessor or any conventional processor.
[0117] The memory 61 can be an internal storage unit of the electronic device 6, such as a hard disk or memory. The memory 61 can also be an external storage device of the electronic device 6, such as a plug-in hard disk, Smart Media Card (SMC), Secure Digital (SD) card, or Flash Card. Furthermore, the memory 61 can include both internal and external storage units of the electronic device 6. The memory 61 is used to store the computer program and other programs and data required by the electronic device. The memory 61 can also be used to temporarily store data that has been output or will be output.
[0118] Those skilled in the art will clearly understand that, for the sake of convenience and brevity, the above-described division of functional units and modules is merely an example. In practical applications, the above functions can be assigned to different functional units and modules as needed, that is, the internal structure of the device can be divided into different functional units or modules to complete all or part of the functions described above. The functional units and modules in the embodiments can be integrated into one processing unit, or each unit can exist physically separately, or two or more units can be integrated into one unit. The integrated unit can be implemented in hardware or as a software functional unit. Furthermore, the specific names of the functional units and modules are only for easy differentiation and are not intended to limit the scope of protection of this application. The specific working process of the units and modules in the above system can be referred to the corresponding process in the foregoing method embodiments, and will not be repeated here.
[0119] Those skilled in the art will clearly understand that, for the sake of convenience and brevity, the specific working processes of the systems, devices, and units described above can be referred to the corresponding processes in the foregoing method embodiments, and will not be repeated here.
[0120] In the above embodiments, the descriptions of each embodiment have different focuses. For parts that are not described in detail or recorded in a certain embodiment, please refer to the relevant descriptions of other embodiments.
[0121] Those skilled in the art will recognize that the units and algorithm steps of the various examples described in conjunction with the embodiments disclosed herein can be implemented in electronic hardware, or a combination of computer software and electronic hardware. Whether these functions are implemented in hardware or software depends on the specific application and design constraints of the technical solution. Those skilled in the art can use different methods to implement the described functions for each specific application, but such implementation should not be considered beyond the scope of this application.
[0122] In the embodiments provided in this application, it should be understood that the disclosed apparatus and methods can be implemented in other ways. For example, the system embodiments described above are merely illustrative. For instance, the division of modules or units is only a logical functional division, and in actual implementation, there may be other division methods. For example, multiple units or components may be combined or integrated into another system, or some features may be ignored or not executed. Furthermore, the coupling or direct coupling or communication connection shown or discussed may be an indirect coupling or communication connection between devices or units through some interfaces, and may be electrical, mechanical, or other forms.
[0123] The units described as separate components may or may not be physically separate. The components shown as units may or may not be physical units; that is, they may be located in one place or distributed across multiple network units. Some or all of the units can be selected to achieve the purpose of the embodiments of this application, depending on actual needs.
[0124] Furthermore, the functional units in the various embodiments of this application can be integrated into one processing unit, or each unit can exist physically separately, or two or more units can be integrated into one unit. The integrated unit can be implemented in hardware or as a software functional unit.
[0125] If the integrated unit is implemented as a software functional unit and sold or used as an independent product, it can be stored in a computer-readable storage medium. Based on this understanding, all or part of the processes in the methods of the above embodiments can also be implemented by a computer program instructing related hardware. The computer program can be stored in a computer-readable storage medium, and when executed by a processor, it can implement the steps of the various method embodiments described above. The computer program includes computer program code, which can be in the form of source code, object code, executable files, or certain intermediate forms. The computer-readable medium can include: any entity or device capable of carrying the computer program code, recording media, USB flash drives, portable hard drives, magnetic disks, optical disks, computer memory, read-only memory (ROM), random access memory (RAM), electrical carrier signals, telecommunication signals, and software distribution media, etc. It should be noted that the content included in the computer-readable medium can be appropriately added or removed according to the requirements of legislation and patent practice in the jurisdiction. For example, in some jurisdictions, according to legislation and patent practice, computer-readable media do not include electrical carrier signals and telecommunication signals.
[0126] The above-described embodiments are only used to illustrate the technical solutions of this application, and are not intended to limit them. Although this application has been described in detail with reference to the foregoing embodiments, those skilled in the art should understand that modifications can still be made to the technical solutions described in the foregoing embodiments, or equivalent substitutions can be made to some of the technical features. Such modifications or substitutions do not cause the essence of the corresponding technical solutions to deviate from the spirit and scope of the technical solutions of the embodiments of this application, and should all be included within the protection scope of this application.
Claims
1. A static deadlock detection method for Java code, characterized in that, include: Generate intermediate representation code and control flow graph of the Java code to be tested; According to the preset pointer analysis rules, thread context-sensitive pointer analysis processing is performed on the intermediate representation code, and a context-complete call graph is constructed based on the result of the pointer analysis processing. Each edge of the call graph is labeled with thread context information. Based on the control flow graph, the lock acquisition order in the execution path of each thread is identified according to the call graph, and a lock acquisition sequence is generated according to the lock acquisition order; By analyzing the lock acquisition sequence, the deadlock detection result of the Java code under test is determined.
2. The method as described in claim 1, characterized in that, Based on the control flow graph, before identifying the lock acquisition order in the execution path of each thread according to the call graph, and before generating a lock acquisition sequence according to the lock acquisition order, the method further includes: The control flow graph is traversed in reverse, and selective anomaly analysis is used to identify and delete execution paths in the control flow graph that are unrelated to lock acquisition operations.
3. The method as described in claim 1, characterized in that, The step of performing thread-context-sensitive pointer analysis on the intermediate representation code according to preset pointer analysis rules includes: According to the pointer analysis rules, the object references and data dependencies related to network callbacks between threads in the intermediate representation code are identified, thereby determining the thread context information.
4. The method as described in claim 1, characterized in that, The step of determining the deadlock detection result of the Java code under test by analyzing the lock acquisition sequence includes: A lock dependency graph is constructed based on the lock acquisition sequence, where nodes represent lock objects and edges represent the dependency relationships of the lock acquisition order. By analyzing the lock dependency graph, the deadlock detection result of the Java code under test is determined.
5. The method as described in claim 4, characterized in that, The step of determining the deadlock detection result of the Java code under test by analyzing the lock dependency graph includes: The existence of cyclic dependency paths in the lock dependency graph is detected using a graph cycle detection algorithm. If a circular dependency path exists in the lock dependency graph, then the Java code under test is determined to have a potential deadlock.
6. The method as described in claim 5, characterized in that, After determining that the Java code under test has a potential deadlock, the method further includes: Based on the relevant information of the potential deadlock and the lock dependency graph, a static deadlock detection report is generated; Output the static deadlock detection report.
7. The method according to any one of claims 1 to 6, characterized in that, The intermediate representation code and control flow graph for generating the Java code to be tested include: Lexical analysis, syntax analysis, and semantic analysis are performed sequentially on the Java code to be tested to generate an abstract syntax tree; The abstract syntax tree is analyzed using a syntax tree parser to extract thread creation points, variable definitions, inheritance relationships, and function call constraints from the Java code under test, in order to generate the intermediate representation code and the control flow graph.
8. A static deadlock detection device for Java code, characterized in that, include: The basic data generation module is used to generate intermediate representation code and control flow graph of the Java code under test; The pointer analysis module is used to perform thread context-sensitive pointer analysis processing on the intermediate representation code according to preset pointer analysis rules, and to construct a context-complete call graph based on the result of the pointer analysis processing, wherein each edge of the call graph is labeled with thread context information. The lock acquisition sequence generation module is used to identify the lock acquisition order in the execution path of each thread based on the control flow graph and the call graph, and generate a lock acquisition sequence based on the lock acquisition order. The deadlock detection module is used to determine the deadlock detection result of the Java code under test by analyzing the lock acquisition sequence.
9. An electronic device comprising a memory, a processor, and a computer program stored in the memory and executable on the processor, characterized in that, When the processor executes the computer program, it implements the static deadlock detection method for Java code as described in any one of claims 1 to 7.
10. A computer program product, characterized in that, When the computer program product is run on an electronic device, the electronic device executes the static deadlock detection method of Java code as described in any one of claims 1 to 7.