Deadlock detection method and device, storage medium and electronic equipment

By generating directed graphs to detect deadlocks in Rust program code, the problem of deadlock detection in Rust language program code is solved, improving the stability and security of the operating system.

CN121705045APending Publication Date: 2026-03-20FUDAN UNIVERSITY +1
View PDF 0 Cites 0 Cited by

Patent Information

Application Number
CN202511640521.8
Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
Filing Date
2025-11-10
Publication Date
2026-03-20

AI Technical Summary

Technical Problem

Existing technologies are insufficient to effectively detect deadlocks that may occur in Rust code, which can negatively impact operating system performance and security.

Method used

By obtaining the compiled Rust program code, the holding state and dependencies of lock objects are determined, a directed graph is generated, and directed cycles are detected, thereby enabling deadlock detection.

Benefits of technology

It effectively detects potential deadlocks in Rust program code, improving the stability and security of the operating system.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN121705045A_ABST
    Figure CN121705045A_ABST
Patent Text Reader

Abstract

The embodiment of the invention discloses a deadlock detection method, which comprises the following steps: according to a compiled to-be-detected Rust program code, determining a holding state of each function in the to-be-detected Rust program code for each lock object during execution, and when the same function in the to-be-detected Rust program code holds a first lock object, obtaining a second lock object, if yes, determining that the second lock object depends on the first lock object, generating a directed graph taking the lock objects as nodes and a directed graph taking the dependency relationship among the lock objects as directed edges according to the dependency relationship among the lock objects, detecting a directed ring in the directed graph, and performing deadlock detection on the to-be-detected Rust program code according to the directed ring. By means of the method, the deadlock situation possibly occurring in the program code written by adopting the Rust language can be effectively detected.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] This specification relates to the field of computer technology, and in particular to a deadlock detection method, apparatus, storage medium, and electronic device. Background Technology

[0002] Deadlock is a phenomenon that occurs during the runtime of a computer operating system, referring to a situation where multiple threads are unable to proceed because they are waiting for resources held by each other. For example, thread A holds lock 1 and attempts to acquire lock 2, but at the same time thread B holds lock 2 and attempts to acquire lock 1. In this case, both threads are waiting for the lock held by the other to be released and cannot proceed.

[0003] Deadlock is a significant type of program vulnerability in operating systems that can impact system performance and security. Due to the high concurrency and logical complexity of operating systems, developers often find it difficult to completely avoid introducing deadlock vulnerabilities when writing code.

[0004] Therefore, how to detect potential deadlocks in the operating system is an urgent problem to be solved. Summary of the Invention

[0005] This specification provides a deadlock detection method, apparatus, storage medium, and electronic device to partially solve the problems existing in the prior art.

[0006] The embodiments in this specification adopt the following technical solutions: This specification provides a deadlock detection method, the method comprising: Obtain the compiled Rust program code to be tested; Identify the lock objects used by the Rust program code to be tested; For each function in the Rust program code to be tested, determine the holding state of each lock object when the function is executed; If the same function in the Rust program code to be detected needs to acquire a second lock object while holding a first lock object, then it is determined that the second lock object depends on the first lock object; the first lock object and the second lock object are any two lock objects among the lock objects. Based on the dependencies between lock objects, a directed graph is generated with lock objects as nodes and the dependencies between lock objects as directed edges. Directed cycles are detected in the directed graph, and deadlock detection is performed on the Rust program code to be detected based on the directed cycles.

[0007] This specification provides a deadlock detection device, the device comprising: The `get` module is used to retrieve the compiled Rust program code to be tested. The lock object determination module is used to determine the lock objects used by the Rust program code to be detected; The holding state determination module is used to determine the holding state of each function for each lock object during execution for each function in the Rust program code to be detected; The dependency determination module is used to determine that if the same function in the Rust program code to be detected needs to acquire a second lock object while holding a first lock object, then the second lock object depends on the first lock object; the first lock object and the second lock object are any two lock objects among the lock objects. The directed graph construction module is used to generate a directed graph with lock objects as nodes and the dependencies between lock objects as directed edges, based on the dependencies between lock objects. The detection module is used to detect directed cycles in the directed graph and perform deadlock detection on the Rust program code to be detected based on the directed cycles.

[0008] This specification provides a computer-readable storage medium storing a computer program that, when executed by a processor, implements the aforementioned deadlock detection method.

[0009] This specification 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 program, it implements the deadlock detection method described above.

[0010] This specification provides a computer program product, which includes a computer program that, when executed by a processor, implements the aforementioned deadlock detection method.

[0011] The above-described at least one technical solution adopted in the embodiments of this specification can achieve the following beneficial effects: This specification discloses a deadlock detection method. Based on the compiled Rust program code to be tested, this method determines the holding state of each function in the Rust program code for each lock object during execution. When the same function in the Rust program code needs to acquire a second lock object while holding a first lock object, it is determined that the second lock object depends on the first lock object. Based on the dependencies between lock objects, a directed graph is generated with lock objects as nodes and the dependencies between lock objects as directed edges. Directed cycles are detected in this directed graph, and deadlock detection is performed on the Rust program code to be tested based on the directed cycles. This method can effectively detect potential deadlock situations in program code written in the Rust language. Attached Figure Description

[0012] The accompanying drawings, which are included to provide a further understanding of this specification and form part of this specification, illustrate exemplary embodiments and are used to explain this specification, but do not constitute an undue limitation thereof. In the drawings: Figure 1 This is a flowchart of the deadlock detection method provided in the embodiments of this specification; Figure 2 This is a schematic diagram of a directed graph provided for an embodiment of this specification; Figure 3 This is a schematic diagram of a deadlock detection device provided in an embodiment of this specification; Figure 4 This is a schematic diagram of the structure of the electronic device provided in the embodiments of this specification. Detailed Implementation

[0013] To make the objectives, technical solutions, and advantages of this specification clearer, the technical solutions of this specification will be clearly and completely described below in conjunction with specific embodiments and corresponding drawings. Obviously, the described embodiments are only a part of the embodiments of this specification, and not all of them. Based on the embodiments in this specification, all other embodiments obtained by those skilled in the art without creative effort are within the scope of protection of this specification.

[0014] The technical solutions provided in the various embodiments of this specification are described in detail below with reference to the accompanying drawings.

[0015] Figure 1 The flowchart of the deadlock detection method provided in the embodiments of this specification specifically includes the following steps: S100: Obtain the compiled Rust program code to be tested.

[0016] In the embodiments of this specification, the following are used: Figure 1 The method shown can be implemented by a deadlock detection tool, which can be deployed on any electronic device, including personal computers, mobile phones, tablets, servers, or server clusters. Specifically, the deadlock detection tool can be deployed on the same electronic device as the Rust program code to be detected, or on different electronic devices; this specification does not impose any restrictions on this.

[0017] Deadlock typically arises when a function in a program's code, already holding one lock object, tries to acquire another. For example, function 1, already holding lock object A, tries to acquire lock object B, while function 2, holding lock object B, tries to acquire lock object A. If these two functions are executed concurrently by two threads, they will become deadlocked, each waiting for the other's lock to be released. Therefore, to detect deadlock in program code, it's necessary to know when each function acquires and releases a lock object.

[0018] For programs written in C or C++, developers typically need to write functions to acquire locks (such as the `Lock` function) and to release locks (such as the `UnLock` function). Unlike C or C++, Rust programs, while also requiring developers to write functions to acquire locks, do not require them to write functions to release locks.

[0019] Specifically, in Rust code, developers can define lock objects using structs. For example, SpinLock is a type of lock object. Developers can define various lock objects using structs; this specification does not distinguish between different lock object types. For each lock object, the Rust code can also define its locking operation API and its return value (LockGuard). The locking operation API is used to acquire the lock object. Once a function in the Rust code uses the locking operation API and obtains its return value, it means that the function has acquired the lock object. Once the function discards the return value, it means that the function has released the lock object.

[0020] Once developers write the locking API in their Rust program code to acquire the lock object, they no longer need to manually write a function to discard the return value of the locking API. When the Rust program code is compiled, the compiler analyzes the lifecycle of the return value of the locking API and automatically adds a function to discard the return value (i.e., the drop function) at the end of the lifecycle of the return value in the Rust program code to release the lock object.

[0021] Therefore, unlike C and C++ languages ​​where the Lock and UnLock functions in uncompiled code can be used to determine when a function acquires and releases a lock object, for Rust code, the deadlock detection tool needs to obtain the Rust code to be tested after compilation by the compiler. This allows the tool to subsequently determine when a function in the Rust code acquires and releases a lock object based on the LockGuard API and the drop function found in the compiled Rust code.

[0022] S101: Determine the lock objects used by the Rust program code to be detected.

[0023] In the embodiments described in this specification, the Rust program code to be tested may contain a lock object marker. This lock object marker can be added by the developer to the Rust program code to be tested, specifically within the structure used to define the lock object. The lock object marked by the lock object marker is the lock object required by the Rust program code to be tested.

[0024] Therefore, the deadlock detection tool can query each lock object tag contained in the Rust program code to be detected, and determine the lock object marked by each queried lock object tag as the lock object used by the Rust program code to be detected.

[0025] S102: For each function in the Rust program code to be detected, determine the holding state of each lock object when the function is executed.

[0026] In the embodiments described in this specification, the Rust program code to be tested may also include a return value flag for the locking operation API corresponding to each lock object. Similarly, the return value flag for the locking operation API can also be added by the developer to the Rust program code to be tested, specifically in the structure used to define the return value in the Rust program code to be tested.

[0027] The holding states described in this specification include both holding and releasing states. For any function in the Rust program code to be tested, the function is also composed of several statements written by the developer. Therefore, the deadlock detection tool needs to determine, for this function, whether the function is holding or releasing each lock object when executing each statement that constitutes the function.

[0028] Specifically, deadlock detection tools first identify the return value of the locking operation API corresponding to each lock object, using the marked return value as the return value for that lock object. Then, they determine which statement within the function acquired the return value and which statement discarded it. The statement that acquired the return value indicates that the function acquired the lock object when executing that statement; the statement that discarded the return value indicates that the function released the lock object when executing that statement.

[0029] Therefore, the deadlock detection tool can first initialize the holding state of the lock object to be released when the function executes to the first statement in the function, and then execute it for each statement contained in the function: If the statement is used to obtain the return value corresponding to the lock object, that is, to determine that the statement has obtained the LockGuard corresponding to the lock object, then it is determined that when the function executes the statement, the function holds the lock object. If the statement is a statement added by the compiler that compiles the Rust program code to be tested, which discards the return value corresponding to the lock object, that is, the dorp function discards the LockGuard corresponding to the lock object, then it is determined that when the function executes the statement, the holding state of the lock object of the function is released.

[0030] The above two cases are the two relatively simple cases in the statements that constitute a function: either the statement is used to obtain the return value corresponding to the lock object, or the statement is used to discard the return value corresponding to the lock object.

[0031] In order to detect all potential deadlock risks in the Rust program code to be tested, that is, to perform deadlock detection on the Rust program code to be tested based on the worst-case scenario, when determining the holding state of a lock object of a function when executing a statement contained therein, the embodiments of this specification also perform the following processing on the following three special statements in the function: If the statement is used to call another function, the holding state of the lock object by the called other function is used as the merging object. If the statement is contained in an execution branch of the function, the holding state of the lock object by the statements contained in all other branches of the function at the time of execution is used as the merging object. If the statement is a return statement of the function, the holding state of the lock object by the function when it reaches the exit statement is used as the merging object. The holding state of the lock object by the function when it reaches the statement is merged with the holding state corresponding to the merging object, and the merging result is re-determined as the holding state of the lock object by the function when it reaches the statement.

[0032] Specifically, the method for merging the holding state of the lock object and the holding state of the merged object when the function executes to this statement is as follows: if at least one of the holding states of the lock object and the merged object is "held" when the function executes to this statement, the merge result is "held". If both the holding state of the lock object and the holding state of the merged object are "released" when the function executes to this statement, the merge result is "released".

[0033] In other words, for the first special type of statement, if the statement's holding of the lock object was originally released when the function executes the statement, but the statement calls another function, and if the called other function holds the lock object, then it is assumed that the function also holds the lock object when it executes the statement.

[0034] For the second special statement, if the statement is one of the execution branches of the function, then the function is considered to have all execution branches holding the lock object as long as any other execution branch holds the lock object.

[0035] For the third special statement, if the statement is a return statement of the function, that is, one of the exit statements of the function, then as long as the function holds the lock object when it executes any other return statement, it is considered that the function holds the lock object when it executes all return statements. This is equivalent to accumulating the holding state of the lock object when the function executes all return statements to the same exit statement.

[0036] Since deadlock occurs when the same function, already holding some lock objects, continues to attempt to acquire other lock objects, the method described above for determining the holding status of lock objects can reasonably be used to suspect that a function is holding a lock object, thus enabling the detection of all potential deadlock risks in subsequent checks.

[0037] In addition, if a statement in a function is neither one of the two simple cases mentioned above nor one of the three special cases mentioned above, then it is determined that the holding state of the function when the function executes the statement is consistent with the holding state of the function when the previous statement was executed.

[0038] S103: If the same function in the Rust program code to be detected needs to acquire a second lock object while holding the first lock object, then it is determined that the second lock object depends on the first lock object; the first lock object and the second lock object are any two lock objects among the lock objects.

[0039] After the deadlock detection tool determines the holding state of each lock object for each function in the Rust program code to be detected when executing each statement in the function through the above step S102, it can determine the dependency relationship between different lock objects.

[0040] Specifically, for any two lock objects (i.e., the first lock object and the second lock object), if the same function in the Rust program code to be tested holds the first lock object and also needs to acquire the second lock object, it means that the second lock object depends on the first lock object.

[0041] For example, suppose a function in the Rust program code to be tested consists of the following four statements in sequence: The first statement is used to retrieve the return value corresponding to the first lock object; The second statement: a statement that does not belong to either of the two simple cases mentioned above, nor to any of the three special statements mentioned above; The third statement is used to retrieve the return value corresponding to the second lock object; The fourth statement is used to discard the return value corresponding to the first lock object.

[0042] In step S102, the deadlock detection tool can determine that when the function executes the first statement, the holding state of the first lock object is "holding". The holding state of the first lock object in the second statement remains unchanged from the first statement, which is also "holding". When the third statement is executed, the holding state of the first lock object is still "holding", but the third statement is used to attempt to acquire the second lock object. Therefore, in step S103, the deadlock detection tool determines that the second lock object depends on the first lock object.

[0043] Conversely, if the order of the third and fourth statements in the example above is reversed, then in step S102, the deadlock detection tool can still determine that the function holds the first lock object when executing the first and second statements, but when executing the third statement, the holding state of the first lock object has changed to release. Therefore, when executing the fourth statement, the function does not attempt to acquire the second lock object while holding the first lock object. Thus, in step S103, the deadlock detection tool can determine that the second lock object does not depend on the first lock object.

[0044] S104: Generate a directed graph with lock objects as nodes and the dependencies between lock objects as directed edges, based on the dependencies between each lock object.

[0045] After determining the dependencies between all lock objects used by the Rust program code to be detected through step S103, the deadlock detection tool can generate a directed graph. This directed graph identifies different lock objects with different nodes and represents the dependencies between lock objects with directed edges. Specifically, if a second lock object depends on a first lock object, then in this directed graph, the node corresponding to the second lock object has a directed edge pointing to the node corresponding to the first lock object.

[0046] S105: Detect directed cycles in the directed graph and perform deadlock detection on the Rust program code to be detected based on the directed cycles.

[0047] The directed cycle described in this specification refers to a closed path in a directed graph that starts from a node, follows the direction of the edges, passes through several other nodes, and finally returns to the starting node.

[0048] Figure 2 This is a schematic diagram of a directed graph provided for embodiments of this specification. Figure 2 In the code, the first lock object corresponds to node 1, and the second lock object corresponds to node 2. If node 1 has a directed edge pointing to node 2, and node 2 also has a directed edge pointing to node 1, then node 1 and node 2 form a directed cycle. This means that in the Rust program code to be tested, there is at least one function that is holding the second lock object while also trying to acquire the first lock object, and at least one other function that is holding the first lock object while also trying to acquire the second lock object. These two functions are very likely to deadlock. Therefore, the deadlock detection tool can generate a detection report based on the lock objects corresponding to the nodes forming the directed cycle and the functions corresponding to the edges forming the directed cycle, allowing developers to optimize or further test the lock objects and functions corresponding to the directed cycle based on the detection report.

[0049] In addition, Figure 1 In step S103, when determining the dependency relationship between two lock objects, specifically for any function in the Rust program code to be detected, determine each statement contained in the function, and for each statement contained in the function, determine the set of lock objects held by the function when it executes the statement, based on the holding state of each lock object when the function executes the statement as determined in step S102, and take all lock objects in the lock object set as the first lock object.

[0050] Next, in a simpler scenario: if the statement itself is used to obtain a second lock object other than the aforementioned set of lock objects, then it can be directly determined that the second lock object depends on all the first lock objects in the aforementioned set of lock objects.

[0051] The more complex first scenario is: if the statement itself is not used to obtain a second lock object other than the above-mentioned set of lock objects, but the statement is used to call other functions, and the other functions being called contain statements for obtaining a second lock object other than the above-mentioned set of lock objects, then in accordance with the principle of detecting all potential risks of deadlock, this specification also considers the second lock object to depend on the second lock object in this case.

[0052] In addition to the more complex first scenario described above, there is also a more complex second scenario: if the statement itself is neither used to acquire a second lock object other than the aforementioned set of lock objects, nor does it call any other function, but the Rust program code to be tested may be interrupted at this statement, and the interrupt handler function after the interruption may contain a statement to acquire the second lock object, then this function in the Rust program code to be tested and the interrupt handler function may also cause a deadlock.

[0053] Therefore, to address the more complex second scenario described above, in this embodiment of the specification, the Rust program code to be tested may also include an interrupt switch marker and an interrupt handler function entry marker. These markers can be added by the developer during the writing of the Rust program code to be tested. The interrupt switch marker is used to mark the interrupt switch API corresponding to each statement, and the interrupt handler function entry marker is used to mark the entry point of the interrupt handler function corresponding to each statement. The interrupt handler function entry point is the entry point for calling the interrupt handler function after a statement is interrupted.

[0054] Deadlock detection tools, for each function in the Rust program code under test, first determine the enabled state of the interrupt switch API corresponding to each statement within that function. The enabled state of the interrupt switch API for a statement includes both enabled and disabled. Specifically, for each statement in a function, the deadlock detection tool first determines the enabled state of the interrupt switch API marked by the interrupt switch flag of that statement. If the interrupt switch API is enabled, it is determined that an interrupt may occur when the function reaches that statement; if the interrupt switch API is disabled, it is determined that an interrupt may not occur when the function reaches that statement.

[0055] Similar to determining the lock holder when a function executes a statement, when the statement is used to call another function, the enable states of the interrupt switch APIs of all statements in the called other functions are used as the merging objects. When the statement is contained in an execution branch of the function, the enable states of the interrupt switch APIs of all other statements in the function are used as the merging objects. When the statement is a return statement of the function, the enable state of the interrupt switch API of the function's exit statement is used as the merging object. After determining the merging objects, the enable states of the interrupt switch APIs of the statement are merged with the enable states corresponding to the merging objects, and the merged result is redefined as the enable state of the interrupt switch APIs of the statement. Specifically, the merging method is as follows: if at least one of the enable states of the statement's interrupt switch APIs and the enable states corresponding to the merging objects is enabled, the merged result is enabled; if both the enable states of the statement's interrupt switch APIs and the enable states corresponding to the merging objects are disabled, the merged result is disabled.

[0056] After determining the enable status of the interrupt switch API for each statement in the Rust program code to be tested using the above method, for each statement of the function, if the interrupt switch API of the statement is enabled, then all interrupt handlers marked by the interrupt handler entry marker of the statement are determined. That is, all interrupt handlers that can be used by the entry point marked by the interrupt handler entry marker of the statement are determined. These interrupt handlers are all interrupt handlers that may be executed after the statement is interrupted. Then, for each interrupt handler, when the interrupt handler contains a statement for acquiring a second lock object other than the above-mentioned lock object set, it is determined that the second lock object depends on all first lock objects in the lock object set. In other words, even if the statement itself is neither a statement for acquiring a second lock object other than the above-mentioned lock object set nor does it call any other function, but the Rust program code to be tested may be interrupted at this statement, and the interrupt handler after the interruption may contain a statement for acquiring a second lock object, then it is still considered that the second lock object depends on all first lock objects in the lock object set. Therefore, directed edges need to be generated in the directed graph pointing from the node corresponding to the second lock object to the nodes corresponding to all first lock objects in the lock object set.

[0057] As can be seen, the above method is based on the principle of detecting all potential risks of deadlock. It not only considers the merging of the holding states of three special statements when determining the holding state of each lock object of each function in the Rust program code to be tested when executing each statement, but also merges the enable states of the interrupt switch APIs of the three special statements when the Rust program code to be tested is interrupted and the interrupt handling function is executed. Therefore, it can detect deadlocks not only in different functions in the Rust program code to be tested, but also in deadlocks between functions in the Rust program code to be tested and interrupt handling functions, which can effectively detect possible deadlock situations.

[0058] The above is a deadlock detection method provided by the embodiments of this specification. Based on the same idea, this specification also provides corresponding devices, storage media and electronic devices.

[0059] Figure 3 This is a schematic diagram of a deadlock detection device provided in an embodiment of this specification. The device includes: Module 301 is used to obtain the compiled Rust program code to be tested. Lock object determination module 302 is used to determine each lock object used by the Rust program code to be detected; The holding state determination module 303 is used to determine the holding state of each function for each lock object during execution for each function in the Rust program code to be detected; The dependency determination module 304 is used to determine that if the same function in the Rust program code to be detected needs to acquire a second lock object while holding a first lock object, the second lock object depends on the first lock object; the first lock object and the second lock object are any two lock objects among the lock objects. The directed graph construction module 305 is used to generate a directed graph with lock objects as nodes and the dependencies between lock objects as directed edges, based on the dependencies between lock objects. The detection module 306 is used to detect directed cycles in the directed graph and perform deadlock detection on the Rust program code to be detected based on the directed cycles.

[0060] Optionally, the Rust program code to be detected contains a lock object marker; The lock object determination module 302 is specifically used to query each lock object marker contained in the Rust program code to be detected; and to determine the lock object marked by each queried lock object marker as the lock object used by the Rust program code to be detected.

[0061] Optionally, the Rust program code to be detected also includes a return value marker for the locking operation API corresponding to the lock object; The holding state determination module 303 is specifically used to, for each lock object, determine the return value marked by the return value of the locking operation API corresponding to the lock object, and use it as the return value corresponding to the lock object; For each statement contained in this function: If the statement is used to obtain the return value corresponding to the lock object, then it is determined that when the function executes the statement, the function holds the lock object. If the statement is a statement added by the compiler that compiles the Rust program code to be tested, which discards the return value corresponding to the lock object, then it is determined that when the function executes the statement, the function's holding state of the lock object is released.

[0062] Optionally, the holding state determination module 303 is further configured to, for each statement contained in the function: If the statement is used to call other functions, the holding state of the lock object by the called other functions will be used as the merged object. If the statement is contained in an execution branch of the function, the holding state of the lock object by the statements contained in all other branches of the function will be used as the merged object. If the statement is the return statement of the function, the holding state of the lock object by the function when the function reaches the exit statement will be used as the merged object. When the function executes to this statement, the holding state of the lock object is merged with the holding state of the merged object, and the merged result is redefined as the holding state of the lock object when the function executes to this statement.

[0063] Optionally, the holding state determination module 303 is specifically used to: when the function executes the statement, if at least one of the holding states of the lock object and the holding states of the merged object is holding, the merging result is holding; when the function executes the statement, if both the holding states of the lock object and the holding states of the merged object are released, the merging result is releasing.

[0064] Optionally, the dependency determination module 304 is specifically configured to: for each function in the Rust program code to be detected, determine the statements contained in that function; for each statement contained in that function, determine the set of lock objects held by that function when it executes that statement, based on the holding state of each lock object when the function executes that statement, and take any lock object in the lock object set as the first lock object; if the statement is a statement used to obtain a second lock object other than the lock object set, then determine that the second lock object depends on the first lock object; or, if the statement is a statement used to call other functions, and the other function being called contains a statement used to obtain a second lock object other than the lock object set, then determine that the second lock object depends on the first lock object.

[0065] Optionally, the Rust program code to be detected also includes an interrupt switch flag and an interrupt handling function entry flag; The dependency determination module 304 is further configured to, if the statement has the interrupt switch flag and the interrupt switch API marked by the interrupt switch flag of the statement is enabled, determine all interrupt handling functions marked by the interrupt handling function entry flag corresponding to the statement. For each interrupt handler function, when the interrupt handler function contains a statement for obtaining a second lock object other than the set of lock objects, it is determined that the second lock object depends on the first lock object.

[0066] This specification also provides a computer-readable storage medium storing a computer program that, when executed by a processor, can be used to perform the deadlock detection method provided above.

[0067] This specification also provides a computer program product comprising a computer program that, when executed by a processor, implements the deadlock detection method described above.

[0068] based on Figure 1 The deadlock detection method shown in this specification also provides embodiments that provide... Figure 4 The diagram shows the structure of the electronic device. Figure 4 At the hardware level, the electronic device includes a processor, internal bus, network interface, memory, and non-volatile memory, and may also include other hardware required for business operations. The processor reads the corresponding computer program from the non-volatile memory into memory and then runs it to implement the deadlock detection method described above.

[0069] The above description is merely an embodiment of this specification and is not intended to limit this specification. Various modifications and variations can be made to this specification by those skilled in the art. Any modifications, equivalent substitutions, improvements, etc., made within the spirit and principles of this specification should be included within the scope of the claims of this specification.

Claims

1. A deadlock detection method, the method comprising: Obtain the compiled Rust program code to be tested; Identify the lock objects used by the Rust program code to be tested; For each function in the Rust program code to be tested, determine the holding state of each lock object when the function is executed; If the same function in the Rust program code to be detected needs to acquire a second lock object while holding a first lock object, then it is determined that the second lock object depends on the first lock object; the first lock object and the second lock object are any two lock objects among the lock objects. Based on the dependencies between lock objects, a directed graph is generated with lock objects as nodes and the dependencies between lock objects as directed edges. Directed cycles are detected in the directed graph, and deadlock detection is performed on the Rust program code to be detected based on the directed cycles.

2. The method as described in claim 1, wherein the Rust program code to be detected contains a lock object marker; Determine the lock objects used by the Rust program code to be tested, specifically including: Query the tokens of each lock object contained in the Rust program code to be detected; Each queried lock object is marked with a tag, and the lock object is determined to be the lock object used by the Rust program code to be detected.

3. The method as described in claim 2, wherein the Rust program code to be detected further includes a return value flag of the locking operation API corresponding to the lock object; The function's holding state for each lock object during execution is determined, specifically including: For each lock object, determine the return value of the lock operation API corresponding to that lock object, marked by the return value flag, and use it as the return value corresponding to that lock object; For each statement contained in this function: If the statement is used to obtain the return value corresponding to the lock object, then it is determined that when the function executes the statement, the function holds the lock object. If the statement is a statement added by the compiler that compiles the Rust program code to be tested, which discards the return value corresponding to the lock object, then it is determined that when the function executes the statement, the function's holding state of the lock object is released.

4. The method of claim 3, further comprising: For each statement contained in this function: If the statement is used to call other functions, the holding state of the lock object by the called other functions will be used as the merged object. If the statement is contained in an execution branch of the function, the holding state of the lock object by the statements contained in all other branches of the function will be used as the merged object. If the statement is the return statement of the function, the holding state of the lock object by the function when the function reaches the exit statement will be used as the merged object. When the function executes to this statement, the holding state of the lock object is merged with the holding state of the merged object, and the merged result is redefined as the holding state of the lock object when the function executes to this statement.

5. The method as described in claim 4, wherein when the function executes to the statement, the holding state of the lock object is merged with the holding state corresponding to the merged object, specifically including: When the function executes this statement, if at least one of the holding states of the lock object and the holding state of the merged object is held, the merge result is held. When the function executes this statement, if both the holding state of the lock object and the holding state of the merged object are released, the merge result is a release.

6. The method as described in claim 1, wherein if the same function in the Rust program code to be detected needs to acquire a second lock object while holding a first lock object, then it is determined that the second lock object depends on the first lock object, specifically including: For each function in the Rust program code to be detected, determine the statements contained in that function; For each statement contained in the function, based on the holding state of each lock object when the function executes the statement, determine the set of lock objects held by the function when the statement is executed, and take any lock object in the set of lock objects as the first lock object; If the statement is used to obtain a second lock object other than the set of lock objects, then the second lock object depends on the first lock object; or, if the statement is used to call another function, and the called function contains a statement to obtain a second lock object other than the set of lock objects, then the second lock object depends on the first lock object.

7. The method as described in claim 6, wherein the Rust program code to be detected further includes an interrupt switch flag and an interrupt handling function entry flag; The method further includes: If the statement has the interrupt switch flag, and the interrupt switch API marked by the interrupt switch flag of the statement is enabled, then all interrupt handling functions marked by the interrupt handling function entry flag corresponding to the statement are determined. For each interrupt handler function, when the interrupt handler function contains a statement for obtaining a second lock object other than the set of lock objects, it is determined that the second lock object depends on the first lock object.

8. A deadlock detection device, the device comprising: The `get` module is used to retrieve the compiled Rust program code to be tested. The lock object determination module is used to determine the lock objects used by the Rust program code to be detected; The holding state determination module is used to determine the holding state of each function for each lock object during execution for each function in the Rust program code to be detected; The dependency determination module is used to determine that if the same function in the Rust program code to be detected needs to acquire a second lock object while holding a first lock object, then the second lock object depends on the first lock object; the first lock object and the second lock object are any two lock objects among the lock objects. The directed graph construction module is used to generate a directed graph with lock objects as nodes and the dependencies between lock objects as directed edges, based on the dependencies between lock objects. The detection module is used to detect directed cycles in the directed graph and perform deadlock detection on the Rust program code to be detected based on the directed cycles.

9. A computer-readable storage medium storing a computer program that, when executed by a processor, implements the method described in any one of claims 1-7.

10. An electronic device comprising a memory, a processor, and a computer program stored in the memory and executable on the processor, wherein the processor, when executing the program, implements the method described in any one of claims 1-7.

11. A computer program product comprising a computer program that, when executed by a processor, implements the method described in any one of claims 1-7.