A multi-thread race condition accurate reproduction method for historical debugging
By constructing a semantic equivalence mapping table and a bidirectional causal chain for cross-architecture synchronization instructions, the problems of causal relationship fragmentation and semantic deviation of synchronization instructions under multi-threaded race conditions are solved, enabling accurate reproduction of multi-threaded race conditions and improving the success rate and consistency of cross-architecture reproduction.
Patent Information
- Application Number
- CN202511892425.2
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2025-12-16
- Publication Date
- 2026-03-03
- Estimated Expiration
- 2045-12-16
AI Technical Summary
Existing multi-threaded deterministic replay technology suffers from problems such as causal relationship fragmentation, semantic deviation of synchronization instructions, insufficient timing precision, and lack of cache visibility in cross-architecture scenarios and fine-grained race condition reproduction, resulting in poor reproduction performance.
By defining three types of causal relationships—release acquisition, wake-up execution, and memory visibility—a semantic equivalence mapping table for synchronous instructions between different target architectures is constructed. User-mode and kernel-mode synchronization events are recorded, and a bidirectional causal chain with confidence is established. During replay, the semantic equivalence mapping table and the causal chain are identified, the semantic reproduction status of core dependent events is verified, the actual hardware execution is ignored, and the semantic reproduction of subsequent events is completed in order of confidence.
It achieves accurate reproduction of race conditions under cross-architecture multi-threaded conditions, improves the success rate of reproducing complex race conditions to 98%, ensures the consistency and timing accuracy of synchronous operation behavior, and solves the problem of implicit race reproduction of cached events.
Smart Images

Figure CN121349841B_ABST
Abstract
Description
Technical Field
[0001] This invention belongs to the field of computer software development technology, specifically relating to a method for accurately reproducing multi-threaded race conditions for historical debugging. Background Technology
[0002] Race conditions in multithreaded programs are among the most difficult defects to debug in software development. They are essentially nondeterministic behaviors caused by uncontrolled interactions between threads. Existing deterministic replay techniques (such as Mozilla RR) reproduce execution trajectories by recording thread scheduling events and synchronization operations. However, they still have significant limitations in cross-architecture scenarios and fine-grained race condition reproduction. Specifically: The problem of fragmented causal relationships: Because existing technologies only record the timing of events without establishing dependencies between them, such as the direct association between thread A releasing a lock and thread B acquiring a lock, the replay process will fail due to broken logic chains when facing complex race conditions with multi-level synchronization dependencies, such as thread B depending on thread A and thread C depending on thread B. The superficial architecture adaptation problem: x86 and ARM have fundamentally different synchronization mechanisms. x86 relies on the `lock` prefix for bus locking, while ARM uses `LDREX` and `STREX` for exclusive access. Existing methods only encapsulate cross-architecture compatibility through unified interfaces, such as the pthread library, without addressing instruction-level semantic mapping, leading to deviations in the reproduction of underlying synchronization instructions. The problem of insufficient timing precision: Instruction counting is used as an event sequence marker, but x86's `lock`... The execution latency of cmpxchg differs from that of ARM's STREX. The actual time difference corresponding to the same instruction count can reach the microsecond level, which is enough to change the triggering conditions of fine-grained race conditions. There is also the issue of missing cache visibility. In a multiprocessor system, memory modifications made by threads need to be synchronized to other cores through cache coherence protocols, such as MESI for x86 and MOESI for ARM. Current technologies do not record cache state changes, which makes it impossible to reproduce implicit race conditions caused by read-after-write visibility latency.
[0003] In summary, existing multi-threaded deterministic replay techniques mainly suffer from technical problems such as broken complex causal chains, semantic deviations in synchronization instructions, distortion of timing markers, and isolated cached events. Summary of the Invention
[0004] In view of this, the present invention provides a method for accurately reproducing multi-threaded race conditions for historical debugging, which realizes accurate reproduction of target programs under cross-architecture multi-threaded race conditions.
[0005] This invention provides a method for accurately reproducing multi-threaded race conditions for historical debugging, specifically including the following steps:
[0006] Step 1: Define causal relationship types for multi-threaded synchronization, including release and acquisition, wake-up and execution, and memory visibility; determine multiple system architectures of the target program to be debugged, denoted as target architectures, and establish a semantic equivalence mapping table between synchronization instructions with equivalent semantics under different target architectures, including equivalent semantics, synchronization instructions corresponding to each target architecture, and equivalence judgment conditions;
[0007] Step 2: Debug and execute the target program in the first target architecture, and record synchronization events including user-mode and kernel-mode synchronization operations, including the execution thread ID, synchronization object ID, synchronization operation timestamp, operation type and execution result. The synchronization events have result arrays and cause arrays. Obtain historical events that satisfy the causal conditions of the current synchronization event, form a causal node with the current synchronization event and historical events, calculate the confidence of the causal node, and add it to the result array of historical events and the cause array of the current synchronization event. The result arrays and cause arrays of all synchronization events form a bidirectional causal chain.
[0008] Step 3: In the second target architecture, start the replay engine. For instructions to be executed that are not synchronous operations, obtain the synchronization object ID, execution thread ID, and operation content. Query the semantic equivalence mapping table to determine the equivalent semantics. Then, obtain the matching original synchronization event from the bidirectional causal chain. Traverse the cause array of the original synchronization event to obtain the core dependency event and complete the semantic reproduction of the core dependency event. Then, complete the semantic reproduction of the instructions to be executed based on the records. Sequence events obtained from traversing the result array of the original synchronization event are sequentially reproduced in descending order of confidence. This process continues until the last instruction to be executed.
[0009] Furthermore, the causal conditions are: having the same synchronization object as the current synchronization event, ending earlier than the start time of the current synchronization event, being a different thread from the current synchronization event, and having a causal relationship with the current synchronization event.
[0010] Furthermore, the execution process of the semantic reproduction includes:
[0011] The system performs memory operations to modify the memory according to the execution results of the corresponding synchronization events in the first target architecture, based on the conditional trigger parameters of the recorded instructions. The system maps the recorded status flags to the corresponding status of the second target architecture, inserts the memory barrier instructions corresponding to the second target architecture, and sets the thread status according to the records. For kernel-mode synchronization operations, the system call return value recorded is returned directly, skipping the actual kernel call.
[0012] Furthermore, while recording synchronization events and bidirectional causal chains, timing data of synchronization command execution is collected, and timing calibration is added during semantic reproduction, including:
[0013] Step 1.1: Calculate the difference between the start time and end time of the synchronization instruction in the first target architecture as the actual delay; if the actual delay deviates from the preset mean by more than a threshold, update the recorded event delay with the actual delay; otherwise, keep the event delay unchanged; calculate the delay standard deviation for the synchronization instructions executed multiple times.
[0014] Obtain the time interval between consecutive events in a bidirectional causal chain to form a bidirectional causal chain event containing time-series data, including delay, interval between consecutive events, standard deviation of delay, and time window type;
[0015] Step 1.2: In the second target architecture, the replay engine obtains the original timing data of the original synchronous event corresponding to the instruction to be executed from the bidirectional causal chain; obtains the event delay of the instruction with equivalent semantics and updates the original timing data; extracts the first original interval between the original synchronous event and the predecessor event, and the second original interval between the original synchronous event and the successor event. When both the first original interval and the second original interval are less than the threshold, if the replay completion timestamp of the predecessor event is less than its sum with the first original interval, then step 1.3 is executed; otherwise, an empty instruction is inserted and the set time is waited before step 1.3 is executed.
[0016] Step 1.3: Perform semantic reproduction. If the difference between the original event delay and the target architecture delay is greater than the threshold, insert an empty instruction; otherwise, skip the set number of instructions after the instruction to be executed.
[0017] Step 1.4: For subsequent events, the sum of the actual delay corresponding to the original synchronous event under the second target architecture and the delay of the preceding non-set instruction of the subsequent event is the theoretical interval, and the difference between the second original interval and the theoretical interval is the first time difference that needs to be compensated.
[0018] If the first time difference is greater than the threshold, a null pointer of the corresponding duration is inserted between the original synchronization event and the subsequent event; otherwise, the non-set instructions are skipped, and the interval between the original target event and the subsequent event is set to the original value.
[0019] Furthermore, the time window types include fine-grained race condition windows and ordinary time windows.
[0020] Furthermore, when the original synchronous event belongs to a fine-grained race window, the replay engine assigns original record timestamps to all events within the window, forcing events to be triggered at the locked timestamp; all instructions within the window are executed instruction by instruction, and after each instruction is executed, the deviation between the current timestamp and the original record timestamp is calculated. If the deviation is greater than the first threshold, an empty instruction is inserted to wait.
[0021] Furthermore, while recording synchronous events and bidirectional causal chains, the capture and synchronization of cached events are added, including:
[0022] Step 2.1: In the first target architecture, record cache events including cache line memory address, cache event type, timestamp, original cache state and new cache state. Obtain the cache line with the same memory address as the synchronization object, bind the synchronization event corresponding to the synchronization object to the cache events within a set time before and after the synchronization event, and supplement the binding relationship to the bidirectional causal chain to form an enhanced causal chain.
[0023] Step 2.2: In the second target architecture, the original synchronization events and related cached events are obtained by matching from the enhanced causal chain based on the synchronization object ID, thread ID, and equivalence semantics;
[0024] Step 2.3: Reproduce the pre-cache events of the instruction to be executed and synchronize the global virtual cache state; complete the semantic reproduction of the instruction to be executed; reproduce the post-cache events of the instruction to be executed and update the global virtual cache.
[0025] Furthermore, only the complete bidirectional causal chain of the most recently set number of events is retained; for deep bidirectional causal chains exceeding the set number of layers, they are compressed into an indirect association between the first and last synchronous events, and only the summary information of the intermediate nodes is retained.
[0026] Furthermore, the target architectures are x86 and ARM.
[0027] Furthermore, historical events that satisfy the causal conditions with the current synchronized event are obtained. If a historical event is unique, then the historical event is the predecessor event of the current synchronized event and the current synchronized event is the successor event of the historical event. A causal node is formed by the ID of the current synchronized event and the ID of the historical event. The confidence of the causal node is calculated, and the causal node and its confidence are added to the result array of the historical event and the cause array of the current synchronized event. If a historical event is not unique, then the causal node with the highest confidence is retained, and its confidence is added to the result array of the corresponding historical event and the cause array of the current synchronized event.
[0028] Beneficial effects:
[0029] This invention constructs a semantic equivalence mapping table of synchronization instructions between different target architectures by defining three types of causal relationships: release acquisition, wake-up execution, and memory visibility. Then, when the target program is executed on the first target architecture, user-mode and kernel-mode synchronization events are recorded. Combined with causal conditions, a bidirectional causal chain with confidence is constructed. During replay, the replay engine is started on the second target architecture. First, the synchronization operation is identified and matched with the original synchronization events in the semantic equivalence mapping table and the causal chain. The semantic reproduction status of the core dependent events is verified. Ignoring the actual hardware execution, memory, status flags, memory barriers, and thread states are forcibly reproduced according to the records. Finally, subsequent events are added to the queue according to the confidence level, and the semantic reproduction of subsequent events is completed in the order of the recorded information. This achieves accurate reproduction of the target program execution process under multi-threaded race conditions. Attached Figure Description
[0030] Figure 1 This is a flowchart illustrating a method for accurately reproducing multi-threaded race conditions for historical debugging, provided by the present invention. Detailed Implementation
[0031] The present invention will be described in detail below with reference to the accompanying drawings and embodiments.
[0032] Cross-architecture replay is typically triggered when it's necessary to trace the execution behavior of architecture A, and this behavior cannot be satisfied through regular cross-platform operation. Specifically, it can include: cross-architecture defect reproduction (when a target program exhibits intermittent defects in a deployment environment of one architecture, but the development or debugging environment is another architecture); cross-architecture security analysis or malware tracing (when malicious code has executed malicious behavior on a device of one architecture, and the attack process needs to be reconstructed in a security analysis environment of another architecture, cross-architecture replay is triggered); cross-architecture compatibility or consistency testing (when a target program needs to support multiple architectures, and it's necessary to verify that the core behavior of the target program is completely consistent across different architectures, cross-architecture replay is triggered); and research and debugging of underlying systems or architectures (when studying the underlying mechanisms of x86 or ARM, or developing cross-architecture basic software, cross-architecture replay is used to verify the correctness of theoretical models or tools).
[0033] This invention provides a method for accurately reproducing multi-threaded race conditions for historical debugging. Its core idea is as follows: Three types of causal relationships are defined: release acquisition, wake-up execution, and memory visibility. A semantic equivalence mapping table of synchronization instructions between different target architectures is constructed. When the target program is executed on the first target architecture, user-mode and kernel-mode synchronization events are recorded. A bidirectional causal chain with confidence is constructed based on the causal conditions. During replay, a replay engine is started on the second target architecture. Synchronization operations are first identified and matched with the original synchronization events in the semantic equivalence mapping table and the bidirectional causal chain. The semantic reproduction status of core dependent events is verified. Ignoring actual hardware execution, memory, status flags, memory barriers, and thread states are forcibly reproduced according to the records. Finally, subsequent events are added to a queue according to their confidence level, and the semantic reproduction of subsequent events is completed sequentially based on the recorded information. This achieves accurate reproduction of the target program execution process under multi-threaded race conditions.
[0034] This invention provides a method for accurately reproducing multi-threaded race conditions for historical debugging, the process of which is as follows: Figure 1 As shown, the specific steps include:
[0035] Step 1: For multi-threaded synchronization, define three causal relationship types based on the behavioral characteristics of synchronization operations: release and acquisition, wake-up and execution, and memory visibility. Determine multiple different system architectures based on the possible running environment or scenario of the target program to be debugged, and denote the system architecture as the target architecture. Based on the analysis of instruction semantics, establish the mapping relationship between synchronization instructions with equivalent semantics under different target architectures, forming a semantic equivalence mapping table. The semantic equivalence mapping table includes equivalent semantics, synchronization instructions corresponding to each target architecture, and equivalence judgment conditions.
[0036] In this context, the release-acquisition causal relationship is as follows: if thread A releases the synchronization object and no other thread intervenes, then thread B immediately and successfully acquires the synchronization object. In this case, thread A's release operation is the direct cause of thread B's acquisition operation, which can be denoted as A.unlock to B.lock. A typical scenario is lock propagation in the producer-consumer model.
[0037] The wake-up execution causal relationship is as follows: thread A wakes up thread B that is waiting on a condition variable, causing thread B to return from the thread blocking state and continue execution. Therefore, thread A is the reason for thread B to start execution, which can be recorded as A.signal to B.wake. The wake-up order must be strictly recorded to avoid deviation in the execution path of multiple waiting threads.
[0038] The memory-visible causal relationship is as follows: after thread A modifies shared memory, thread B reads the modified value and executes based on the result. Therefore, thread A's write operation is the implicit cause of thread B's read operation, which can be denoted as A.write to B.read. The core solution is to address the timing record problem of implicit race conditions.
[0039] For x86 and ARM synchronization instructions, the semantic equivalence mapping table constructed in this invention represents the mapping relationship between x86 architecture core synchronization instructions and ARM architecture core synchronization instructions. For example, the x86 instruction `lock cmpxchg [addr], rbx` and the ARM instructions `LDREX r0, [addr]; CMP r0, r1; STREX r2, r3, [addr]` have equivalent semantics. The equivalence determination condition is to verify that the triggering conditions, final memory values, and status flags of the two instructions are consistent.
[0040] Step 2: The target architecture for debugging the target program is the first target architecture. The debugger executes the target program in the first target architecture and adopts a hardware-level instruction tracing method adapted to the first target architecture to monitor the instruction execution process of the target program in real time, identify and record user-mode synchronization operations including atomic operations and synchronization library function calls; adopt a system call interception method adapted to the first target architecture to identify and record kernel-mode synchronization operations, including synchronization operation type, synchronization object ID and operation execution result.
[0041] Synchronization events are composed of recorded user-mode and kernel-mode synchronization operations, including the executing thread ID, synchronization object ID, synchronization operation timestamp, operation type, and execution result; each synchronization event has a result array and a cause array to store causal relationship information.
[0042] Write the current synchronized event into the global event queue in chronological order, and iterate through the historical events within the set time window in the global event queue. If there is only one historical event that satisfies the causal condition with the current synchronized event, then the historical event is the predecessor event of the current synchronized event, and the current synchronized event is the successor event of the historical event. A causal node is formed by the ID of the current synchronized event and the ID of the historical event. The confidence of the causal node is calculated, and the causal node and its confidence are added to the result array of the historical event and the cause array of the current synchronized event. If there are multiple historical events, retain the causal node with the highest confidence and add it and its confidence to the result array of the corresponding historical event and the cause array of the current synchronized event.
[0043] A bidirectional causal chain is formed by the result array and cause array of all events in the global event queue. The bidirectional causal chain is a traceable and constrained dependency link that connects the influence and being influenced relationships of different threads based on the same synchronization object.
[0044] The causal conditions are: events that share the same synchronization object as the current synchronization event, whose end time is earlier than the start time of the current synchronization event, belong to a different thread than the current synchronization event, and have a causal relationship with the current synchronization event. The smaller the time interval between the current synchronization event and historical events, the higher the confidence of the causal node. The synchronization object ID can be represented by the memory address of the synchronization object.
[0045] Furthermore, to avoid the infinite growth of bidirectional causal chains, this invention introduces a sliding window mechanism, specifically: only retaining the complete bidirectional causal chain of the most recent set number of events; compressing deep bidirectional causal chains exceeding a set number of layers into an indirect association between the first and last synchronous events, and retaining only summary information for intermediate nodes.
[0046] Step 3: The target architecture of the replay debugging target program is the second target architecture. The replay engine is started in the second target architecture. The replay engine decodes the current instruction stream to identify the instruction to be executed. For the instruction to be executed that is a user-mode synchronization operation or a kernel-mode synchronization operation, the semantic equivalence mapping table is queried to determine its corresponding equivalent semantics and equivalence judgment conditions. Based on the behavioral characteristics of the instruction to be executed, its causal relationship type is determined, and the synchronization object ID, execution thread ID and operation content are extracted.
[0047] Based on the synchronization object ID, execution thread ID, and equivalent semantics, obtain the synchronization event under the first target architecture that matches the instruction to be executed from the bidirectional causal chain, record it as the original synchronization event, and extract its causal relationship information; based on the causal relationship type, traverse the cause array of the original synchronization events and select the predecessor event of the causal relationship. If there are multiple predecessor events, retain the predecessor event with the highest confidence as the core dependency event; otherwise, use the predecessor event as the core dependency event.
[0048] Check if the semantic reproduction of the core dependency event has been performed. If not, suspend the current operation, complete the semantic reproduction of the core dependency event, and proceed to step 4; otherwise, proceed to step 4.
[0049] Step 4: Ignore the actual execution of the instruction to be executed in the second target architecture, and complete the semantic reproduction of the instruction to be executed based on the recorded information; according to the causal relationship type, traverse the result array of the original synchronous events and select the causal successor events, and add the sorted successor events to the execution queue of the replay engine in descending order of confidence, and set the core dependency event of the successor event as the original synchronous event, and complete the semantic reproduction of the successor event based on the recorded information; continue in this manner until the last instruction to be executed is completed and the semantic reproduction of the target program ends.
[0050] The execution process of semantic reproduction in this invention includes:
[0051] According to the record, set the conditional trigger parameters of the semantic reproduction related instructions, perform memory operations to modify the memory according to the execution result of the corresponding synchronization event in the first target architecture, and ensure that the memory is consistent with the record; map the status flag of the record to the corresponding status of the second target architecture, insert the memory barrier instruction corresponding to the second target architecture, and set the thread status according to the record; for kernel-mode synchronization operations, directly return the system call return value of the record, skip the real kernel call; so that the target program has the same execution state as the first target architecture.
[0052] To ensure timing consistency during replay, this invention, while executing the target program in the first target architecture, simultaneously records synchronization events and bidirectional causal chains, and collects timing data on the execution of synchronization instructions to provide a basis for replay calibration. Furthermore, it adds timing calibration logic based on the semantic reproduction of synchronization operations, specifically including:
[0053] Step 1.1: Using hardware-level instruction tracing, obtain the execution start timestamp and execution end timestamp of the synchronization instruction, calculate the difference between the execution end timestamp and the execution start timestamp, and this difference is the actual delay; query the delay database for the preset delay range of the synchronization instruction. If the actual delay deviates from the preset average value by more than a threshold, update the delay value of the instruction in the database to the actual delay; otherwise, leave it unchanged.
[0054] For multiple executions of the same synchronization command, the cumulative delay standard deviation is calculated and stored in the delay database to statistically analyze delay fluctuations.
[0055] The actual delay of the instruction and the time window type to which it belongs are supplemented in the synchronous event, and the time interval between the preceding and following events in the causal chain are associated, that is, the difference between the execution end time of the synchronous event and the execution start time of the preceding event, forming a bidirectional causal chain with time sequence marking that includes event delay, the interval between preceding and following events, the standard deviation of delay and the time window type.
[0056] The time window types include fine-grained race condition windows and ordinary time windows.
[0057] Step 1.2: Start the replay engine in the second target architecture, obtain the original timing data of the original synchronous events corresponding to the instruction to be executed from the bidirectional causal chain; query the calibrated event delay of the instruction with equivalent semantics in the second target architecture from the delay database, and update the original timing data with the calibrated event delay.
[0058] Add extraction of time-series correlation data, including the first event delay of the predecessor event of the original synchronous event, the first original interval between the original synchronous event and the predecessor event, and the second original interval between the original synchronous event and the successor event;
[0059] When both the first and second original intervals are less than the threshold, it indicates that the original synchronization event belongs to the fine-grained race window. Then, check whether the replay completion timestamp of the predecessor event satisfies that its sum with the first original interval is not less than the current replay timestamp. If it does not satisfy the condition, insert a small number of empty instructions to wait, so as to avoid the timing window closing prematurely. Otherwise, the fine-grained timing pre-check is passed and step 1.3 is executed.
[0060] Step 1.3: Perform semantic reproduction and instruction delay calibration. Calculate the difference between the original event delay and the target architecture delay as the delay deviation. If the delay deviation is greater than the threshold, insert an empty instruction with the same execution time as the delay deviation. Otherwise, skip irrelevant non-critical instructions after the instruction to be executed, compress the execution time, and ensure that the delay deviation is the same as the set value.
[0061] Step 1.4: For subsequent events, the target start time of the subsequent event is obtained by summing the replay completion time of the original synchronous event and the second original interval. Then, the theoretical interval is obtained by summing the calibrated delay of the original synchronous event under the second target architecture and the pre-instruction delay of the subsequent event. The difference between the second original interval and the theoretical interval is the first time difference that needs to be compensated.
[0062] If the time difference is greater than the threshold, a null pointer of the corresponding duration is inserted between the original synchronous event and the subsequent event; otherwise, non-critical instructions are skipped, and the interval between the original target event and the subsequent event is forced to be the original value.
[0063] Furthermore, when the original synchronization event belongs to a fine-grained race condition window, in order to ensure that the race condition triggering conditions are completely reproduced, the present invention adds the following processing steps:
[0064] Global timestamp locking: The replay engine assigns original record timestamps to all events within the window, ignoring actual hardware execution delays and forcing events to be triggered at the locked timestamp.
[0065] Instruction-level step calibration executes all instructions within the window one instruction at a time. After each instruction is executed, the current timestamp is read and compared with the original recorded timestamp. If the deviation exceeds the first threshold, an empty instruction is inserted for adjustment.
[0066] Cache state collaborative calibration, combined with the memory barrier rules of the semantic mapping table, forces the insertion of architecture-specific strong memory barriers within a fine-grained window to ensure that cache visibility latency is consistent with the original execution and avoids implicit race-time offsets;
[0067] Multi-core clock synchronization ensures that the instruction execution progress of different cores is aligned through the inter-core synchronization signal of the global virtual clock, avoiding fine-grained window misalignment caused by inter-core clock deviation.
[0068] To further address the challenge of reproducing implicit race conditions caused by cache state changes triggered by synchronization operations during code debugging, this invention, when executing the target program in the first target architecture, adds the capture and synchronization of cache events while recording synchronization events and bidirectional causal chains. This provides a basis for reproducing memory visibility during the replay phase, specifically including:
[0069] Step 2.1: Use a cache event capture tool adapted to the first target architecture to record cache events, including invalidation, shared state switching, exclusive preemption, etc. Cache events include cache line memory address, cache event type, timestamp, original cache state, and new cache state; obtain the cache line with the same memory address as the synchronization object, bind the synchronization event corresponding to the synchronization object to the cache events within a set time before and after the synchronization event, and supplement the binding relationship to the bidirectional causal chain to form an enhanced causal chain.
[0070] Step 2.2: Start the replay engine in the second target architecture and match the original synchronization events and related cached events from the enhanced causal chain based on the synchronization object ID, thread ID and equivalence semantics.
[0071] Step 2.3: Reproduce the pre-cache events of the instruction to be executed and synchronize the global virtual cache state; complete the semantic reproduction of the instruction to be executed; reproduce the post-cache events of the instruction to be executed and update the global virtual cache.
[0072] Among them, pre-cache events refer to cache consistency events associated with a synchronization event that occur before the synchronization event begins. They are used to reproduce the cache environment before the synchronization operation is executed, ensuring that the triggering conditions and memory visibility basis of the synchronization operation are consistent with the original execution. Post-cache events refer to cache consistency events associated with a synchronization event that occur after the synchronization event ends. They are used to reproduce the cache state changes after the synchronization operation is executed, ensuring that subsequent threads that depend on the synchronization operation can obtain memory visibility consistent with the original execution.
[0073] Example:
[0074] This embodiment takes x86 and ARM architectures as examples and employs a method for accurately reproducing multi-threaded race conditions for historical debugging provided by this invention. It achieves high-precision reproduction of fine-grained race conditions across platforms. The specific process includes:
[0075] S1, Instruction-level Causal Chain Enhanced Event Recording. By establishing dependency links from operations to responses between synchronous events, discrete events are chained together into a continuous logic chain, resolving the problem of logical breakage in the reproduction of complex race conditions. Differentiated but logically unified capture processes are designed for the hardware characteristics of x86 and ARM:
[0076] S1.1, x86 architecture capture logic.
[0077] S1.1.1 Record instruction execution flow using Intel PT (Processor Trace) hardware tracing technology to identify lock prefix instructions (atomic operations) and call pthread_* (library function synchronization).
[0078] S1.1.2. For the futex system call (kernel-mode synchronization), intercept and record the input parameters (synchronization object address, operation type) and return value using ptrace;
[0079] S1.1.3 Maintain a global event queue. Each event contains a source thread ID, a target thread ID, a synchronization object address, and an occurrence timestamp. When a synchronization operation of B is detected to be immediately following an operation of A and acting on the same object, a causal relationship is established.
[0080] S1.2, ARM architecture capture logic.
[0081] S1.2.1. Use CoreSight ETM (Embedded Trace Macrocell) to trace instruction execution and identify LDREX and STREX sequences (exclusive access) and bl pthread_* (library function calls).
[0082] S1.2.2. For futex system calls, intercept them through perf event monitoring and record the parameters in registers r0 to r3 (ARM system call parameters are passed through registers).
[0083] S1.2.3. It adopts the same global event queue format as x86, and only adapts the ARM 32-bit instruction encoding at the instruction parsing layer, such as the opcode of STREX being 0xE85D0F10.
[0084] S1.3 Causal chain data structure and construction.
[0085] Design a hierarchical data structure to bind events to causal relationships, as follows:
[0086] / / Basic synchronization events
[0087] typedef struct {
[0088] uint64_t event_id; / / Globally unique ID
[0089] uint8_t arch; / / 0=x86, 1=ARM
[0090] SyncOpType op_type; / / Operation type (lock / unlock / signal, etc.)
[0091] uint64_t thread_id; / / Execution thread ID
[0092] uint64_t sync_addr; / / Address of the synchronization object (such as the lock address)
[0093] uint64_t start_time; / / Start time stamp (nanoseconds) for the operation
[0094] uint64_t end_time; / / Operation end timestamp (nanoseconds)
[0095] uint8_t result; / / Operation result (success / failure)
[0096] } SyncEvent;
[0097] / / Causal Node
[0098] typedef struct {
[0099] uint64_t src_event_id; / / Source event ID (e.g., unlock event)
[0100] uint64_t dest_event_id; / / Target event ID (e.g., lock event)
[0101] CausalType type; / / Causal type (release-acquisition, etc.)
[0102] uint32_t confidence; / / Association confidence level (0-100, based on time interval)
[0103] } CausalNode;
[0104] / / Enhanced events (including causal relationships)
[0105] typedef struct {
[0106] SyncEvent base; / / Base event
[0107] CausalNode* causes; / / The cause of the current event (input cause and effect)
[0108] CausalNode* effects; / / The results caused by the current event (output causality)
[0109] uint8_t cause_count; / / Input the number of causes
[0110] uint8_t effect_count; / / Output the number of causal events
[0111] EnhancedEvent;
[0112] The build process includes:
[0113] Event capture: Record all synchronization operations in real time using well-known techniques such as API hooking or instruction instrumentation, generate a SyncEvent and assign a unique event_id; Causal identification: For a newly captured event E, iterate through historical events within the last 100ms. If an event F exists that satisfies the following condition:
[0114] F and E operate on the same synchronization object;
[0115] F's end_time < E's start_time;
[0116] The thread of F is different from the thread of E;
[0117] Then create a CausalNode (src_event_id=F.event_id, dest_event_id=E.event_id) and calculate the confidence score;
[0118] Link integration involves adding CausalNodes to the effects of F and the causes of E respectively, forming a bidirectional causal chain; conflict handling involves retaining the association with the highest confidence level if multiple events may lead to E, such as multiple threads releasing the same lock, ensuring the shortest time interval.
[0119] S1.4 Maintenance and pruning of complex causal chains.
[0120] Only the complete causal chains of the most recent 1000 events are retained. For older events, only the top-level associations of direct input / output causality are retained. For deep causal chains with more than 10 levels, such as those consisting of A, B, C, ..., K, they are automatically compressed into indirect associations from A to K, while retaining the summary information of intermediate nodes.
[0121] When a cycle is detected, such as A to B and B to A, it is marked as a special type of mutual dependency, and the execution order of events within the cycle is guaranteed first during replay.
[0122] This invention establishes the concept of instruction-level causal chain, which solves the problem of broken reproduction logic caused by multi-level synchronous dependencies in traditional methods by connecting discrete events through dependencies, and improves the success rate of reproducing complex race conditions involving more than three threads to 98%. The bidirectional causal association design supports both forward tracing and reverse deduction, providing a complete logical clue for reverse debugging.
[0123] S2. Semantic mapping and simulation of architecture-specific synchronization instructions. A semantically equivalent mapping mechanism is designed to address the characteristics of synchronization instructions in x86 and ARM architectures, ensuring consistent behavior of synchronization operations when reproducing across different architectures.
[0124] S2.1 Semantic extraction and classification of synchronization instructions.
[0125] S2.1.1, x86 architecture core synchronization instructions:
[0126] `lock cmpxchg [addr], reg`: Atomic comparison swap. If `[addr]` equals `eax`, then `reg` is written to `[addr]` and `ZF` is set to 1; otherwise, `[addr]` is read into `eax` and `ZF` is set to 0. Its core semantics are conditional modifications based on comparison, ensuring atomicity.
[0127] `lock add [addr], imm`: This is an atomic addition operation that adds `imm` to `[addr]`. Its core semantic is unconditional modification, ensuring atomicity.
[0128] `call pthread_mutex_lock`: Acquires a user-space lock. Returns immediately on success, and blocks until the lock is released on failure. Its core semantics are blocking mutual exclusion access control.
[0129] syscall futex (SYS_futex): A kernel-mode synchronization primitive that supports wait and wake-up semantics. Its core semantics are based on the kernel's inter-thread notification mechanism.
[0130] S2.1.2, ARM architecture core synchronization instructions:
[0131] LDREX r0, [addr]; STREX r1, r2, [addr]: Exclusive loading and storage. LDREX marks addr as exclusive access. STREX only writes to r2 to [addr] if the exclusive mark has not been cleared, and stores the result (0 = success, 1 = failure) in r1. The core semantics are consistent with lock cmpxchg, which is conditional modification based on exclusivity.
[0132] LDADD r0, r1, [addr]: Atomic addition, adds r0 to [addr] and stores the old value in r1. The core semantics are consistent with lock add, which is an unconditional atomic modification.
[0133] bl pthread_mutex_lock: The semantics are completely consistent with the x86 pthread_mutex_lock, only the function calling convention is different. ARM jumps through the bl instruction and the return address is stored in the lr register.
[0134] svc #0 (futex system call): Consistent with the futex semantics of x86, except that parameters are passed through r0-r3 (x86 uses rdi-rsi).
[0135] S2.2 Construction of the semantic equivalence mapping table.
[0136] Based on the semantic extraction results, a cross-architecture synchronous semantic mapping table is constructed to ensure behavioral equivalence.
[0137] x86 commands / operations ARM Instructions / Operations Equivalence semantic verification standard lock cmpxchg [addr], rbx LDREX r0, [addr]; CMP r0, r1; STREX r2, r3, [addr] 1. The triggering conditions for condition modification are consistent. 2. The final memory values are consistent. 3. The status flags (ZF / r2) are consistent. lock add qword ptr [addr], 1 LDADD r0, r1, [addr] (r0=1) 1. Consistent memory increments. 2. Atomicity guarantees consistency. pthread_mutex_lock(addr) pthread_mutex_lock(addr) 1. Successful / failed lock acquisition results are consistent. 2. Blocking behavior is consistent. futex(addr, FUTEX_WAIT, val) futex(addr, FUTEX_WAIT, val) 1. Waiting conditions are the same. 2. Wake-up timing is the same.
[0138] The verification criteria of the mapping table ensure that the input-to-output behavior of cross-architecture operations is completely consistent. For example, lockcmpxchg and LDREX and STREX sequences must produce the same memory results and status flags under the same initial state.
[0139] S2.3 Deterministic simulation of instruction execution results. During replay, the semantics are forcibly reproduced based on the recorded results, without relying on the actual execution of hardware instructions.
[0140] S2.3.1, x86 instruction simulation:
[0141] For lock cmpxchg, the replay engine directly reads the comparison result of the record (success or failure). If successful, it writes the new_val of the record to memory and sets ZF=1. Otherwise, it keeps the memory value unchanged and sets ZF=0, completely ignoring the actual hardware execution result.
[0142] For pthread_mutex_lock, during replay, it directly returns whether the record was successfully acquired. If the record is blocked, it forces the thread state to be set to WAITING and adds it to the waiting queue, regardless of the actual lock state.
[0143] S2.3.2, ARM Instruction Simulation:
[0144] For STREX, during replay, the recorded result (0 or 1) is forced to be written to register r2, even if the actual hardware execution may succeed (0) or fail (1).
[0145] For LDADD, during replay, the recorded old_val (value before operation) is directly stored in r1, and old_val + r0 is written to memory, ignoring the hardware calculation result.
[0146] S2.3.3 Unified processing of system calls:
[0147] For system calls like futex, the replay function directly returns the recorded return value, skipping the actual kernel call. For example, x86 records futex returning 0 (successful wake-up), while ARM replay forces a return value of 0 regardless of the kernel state.
[0148] S2.4 Cross-architecture adaptation of register states.
[0149] The register sets of x86 and ARM differ significantly, requiring state mapping during playback:
[0150] In synchronous operation, both the x86 rax (accumulator) and the ARM r0 (first parameter register) play the role of value passing. During replay, it is necessary to ensure that the logical values of the two are consistent.
[0151] Key flags (such as the zero flag ZF / Z) in x86's eflags (flag register) and ARM's cpsr (program status register) need to be semantically mapped to ensure consistent conditional jump behavior.
[0152] Based on a semantically equivalent mapping mechanism, it breaks through the limitations of instruction-level compatibility, solves the behavioral deviations caused by the differences in synchronous instruction sets between x86 and ARM, and improves cross-architecture replay consistency to 99%; the hard-coded simulation of instruction results is completely independent of the hardware environment, ensuring that the synchronous operation results under the same input are completely consistent across different architectures; the semantic-level mapping of register states focuses only on the key registers that affect synchronous behavior, reducing the overhead of recording irrelevant states.
[0153] S3. Dynamic timing calibration based on instruction delay model.
[0154] By establishing an instruction-level latency model, the differences in instruction execution cycles between x86 and ARM are corrected, ensuring that the time interval of events during cross-architecture replay is consistent with the records.
[0155] S3.1 Construction and dynamic calibration of instruction delay database.
[0156] Instruction latency refers to the time from the start of instruction execution to its completion, and is affected by architecture, microarchitecture, and operands. Construct a latency database containing core synchronous instructions:
[0157] S3.1.1 Basic Delay Data Acquisition:
[0158] Based on official Intel / ARM hardware documentation and test data, the latency of typical instructions in typical environments is preset as follows:
[0159] x86 instructions Delay (ns) ARM instructions Delay (ns) lock cmpxchg 15-20 LDREX+STREX 12-16 lock add 10-12 LDADD 8-10 pthread_mutex_lock (Success) 20-30 pthread_mutex_lock (Success) 18-25 futex system call 250-300 futex system call 230-280
[0160] S3.1.2 Dynamic calibration mechanism:
[0161] During the recording phase, the actual latency (end_time - start_time) of each synchronization instruction is measured in real time. If the deviation from the database value exceeds 20%, the database is updated (retaining the corrected value for the current architecture). For example, on an ARM Cortex-A72 with a certain workload, the measured latency of LDREX+STREX is 14ns, and this value in the database will be updated to 14ns.
[0162] S3.1.3, Delay fluctuation compensation:
[0163] For multiple executions of the same instruction, the standard deviation σ of the delay is calculated. If the deviation between the simulated delay and the recorded value exceeds σ during replay, compensation is made by fine-tuning the delay of subsequent instructions to ensure that the cumulative error is no greater than 5ns.
[0164] S3.2, Delay compensation algorithm for event timing.
[0165] During replay, it is necessary to ensure that the time interval of cross-architecture events is consistent with the recording. The core is to calculate and compensate for the differences in instruction latency between different architectures.
[0166] Let the event sequence of the recording phase x86 be E1(t1) to E2(t2), and the time interval Δt = t2 - t1;
[0167] In the replay stage ARM, the occurrence time of E1' is t1', and the target occurrence time of E2' needs to be calculated as t2' = t1' + Δt;
[0168] In actual execution, the theoretical delay from E1' to E2' is Δt_arm (based on the ARM delay database), so the compensation value Δc = Δt - Δt_arm; if Δc > 0, it means that ARM executes faster, so a no-op instruction of duration Δc is inserted between E1' and E2'; otherwise, non-critical instructions between E1' and E2', such as irrelevant arithmetic operations, are skipped to compress the execution time.
[0169] Example:
[0170] In the x86 record, E1 (lock cmpxchg) occurs at t1 = 1000 ns, E2 (futex) occurs at t2 = 1315 ns, and Δt = 315 ns;
[0171] During ARM playback, the LDREX+STREX delay of E1' is 14ns (t1'=2000ns), and the theoretical futex delay of E2' is 280ns. Therefore, Δt_arm=14+280=294ns.
[0172] The compensation value Δc = 315 - 294 = 21ns, so 21 empty instructions need to be inserted (ARM's nop is about 1ns per instruction, so 21 instructions need to be inserted) to ensure that E2' occurs at t2' = 2000 + 315 = 2315ns.
[0173] S3.3 Precise control of fine-grained timing constraints.
[0174] For events with a time interval of no more than 50 ns, a high-precision control mechanism is enabled:
[0175] Instruction-level stepping: The replay engine executes instructions one by one, checking the current timestamp after each instruction. If the target time has not been reached, a nop is inserted.
[0176] Timestamp locking: For events within a race window, such as the interval between A releasing the lock and B acquiring the lock not exceeding 20ns, their timestamps are locked as recorded values, ignoring actual execution delays;
[0177] In multi-core synchronization and multi-processor scenarios, the timing of events on all cores is forcibly controlled by a global virtual clock to avoid timing deviations caused by clock skew between cores.
[0178] Based on the instruction latency model, this method incorporates the differences in hardware instruction execution latency into cross-architecture calibration for the first time, reducing the replay error of cross-architecture event intervals from microseconds to less than 5ns. The combination of dynamic compensation and fine-grained control ensures overall timing consistency and accurately reproduces the critical time windows of fine-grained race conditions. The dynamic update mechanism of the latency database enables the method to adapt to different microarchitectures, such as Skylake and Ice Lake on x86, and Cortex-A7 and A53 on ARM.
[0179] S4, replay scheduling driven by dual events of caching and synchronization. This deeply binds cache consistency events with synchronization operations, reproducing the implicit race condition caused by cache visibility through a dual-event-driven mechanism.
[0180] S4.1 The binding mechanism between cache and synchronization events: Cache state changes are the basis for memory visibility between threads and must be tightly bound to synchronization events.
[0181] S4.1.1 Classification and Capture of Cached Events:
[0182] x86 architecture: Monitor cache line status and record data via Intel VT-x's EPT (Extended Page Table).
[0183] The cache line moves from modified state (M) to shared state (S), synchronizing data to other cores;
[0184] A cache line invalidation request initiated by a remote core invalidates the current core's cache.
[0185] The cache line moves from exclusive state (E) to invalid state (I) and is modified by other cores.
[0186] ARM architecture: Monitors and records cached events through the CoreSight PMU performance monitoring unit:
[0187] STREX failed because exclusive access was preempted, indicating that the cache line has been modified.
[0188] Cache line migration, such as from L1 to L3, may lead to increased access latency;
[0189] Global monitoring events, and other checks for access to the same cache line.
[0190] S4.1.2 Synchronization and Cache Event Binding Structure:
[0191] typedef struct {
[0192] uint64_t cache_addr; / / Cache line address (64-byte aligned)
[0193] CacheEventType type; / / Cache event type (invalidation / sharing, etc.)
[0194] uint64_t cpu_id; / / The CPU core ID where the event occurred
[0195] uint64_t timestamp; / / Event timestamp
[0196] uint8_t prev_state; / / Cached state before the event
[0197] uint8_t curr_state; / / Cached state after the event
[0198] } CacheEvent;
[0199] / / Synchronous-Cache Binding Pair
[0200] typedef struct {
[0201] EnhancedEvent sync_event; / / Enhanced synchronization event
[0202] CacheEvent related_cache[4]; / / Related cache events (up to 4)
[0203] uint8_t cache_count; / / Number of cached events
[0204] } SyncCacheBundle;
[0205] S4.1.3 Binding Rules:
[0206] When the address of a synchronization event, such as a lock address or a shared memory address, falls into a cache line, all cached events within 50ns before and after the synchronization event in that cache line are marked as associated events and stored in the SyncCacheBundle. For example, if thread A's unlock operation address is 0x7f000008, which belongs to cache lines 0x7f000000 to 0x7f00003f, then shared-state switching events within 50ns before and after the unlock in that cache line will be bound to that unlock event.
[0207] S4.2, Dual event-driven replay logic: The replay engine schedules based on both synchronous events and cached events to ensure that memory visibility is consistent with the records.
[0208] S4.2.1, Preloading cached events:
[0209] Before replaying a specific synchronous event, first reproduce its associated pre-buffered event (timestamp < sync_event.start_time):
[0210] If the associated event is cache invalidation, the corresponding cache line of the current thread is forced to be invalidated to simulate hardware cache behavior; if the associated event is shared state switching, the cache behavior is marked as shared state to prevent exclusive access by subsequent operations.
[0211] S4.2.2, Synchronous Event Execution:
[0212] Synchronization instructions are executed according to semantic simulation logic to ensure that the execution result is consistent with the record. At the same time, new cache states generated during the execution process are recorded, such as lock operations that may set cache lines to exclusive state.
[0213] S4.2.3, Post-processing of cached events:
[0214] After the synchronous event completes, reproduce its associated cached event (timestamp > sync_event.end_time):
[0215] If the associated event is cache sharing, the modification of the current cache line will be synchronized to the global virtual cache to simulate cache synchronization between multiple cores; if the associated event is remote cache migration, the new position of the cache line will be recorded, affecting the latency calculation of subsequent memory accesses.
[0216] S4.2.4, Consistency Verification:
[0217] During replay, the results of synchronization events are periodically cross-validated with the status of cached events. For example, if a STREX record fails, it indicates preemption, and there must be a related event indicating that the cached line has been modified by another core; otherwise, calibration is triggered, which forces the insertion of a virtual cached event.
[0218] S4.3, Normalized simulation of cross-architecture caching protocols.
[0219] The x86 MESI (Modify, Exclusive, Shared, Invalidate) protocol differs from the ARM MOESI (Add Ownership) protocol and needs to be normalized.
[0220] State normalization mapping:
[0221] The modification (M) of MESI and the ownership (O) of MOESI are uniformly mapped to an exclusive modifiable state;
[0222] The exclusive (E) state of MESI and the exclusive (E) state of MOESI are uniformly mapped to an exclusive and unmodifiable state;
[0223] The shared (S) and invalid (I) states of the two correspond directly.
[0224] Behavior normalization:
[0225] Regardless of the original protocol, replay is handled uniformly according to the state transition logic from exclusive to shared, ensuring consistent cache synchronization behavior across different architectures. For example, both M-to-S on x86 and O-to-S on ARM are considered data synchronization to other cores, triggering the same subsequent events.
[0226] Compared to existing technologies, this invention improves the ability to reproduce complex race conditions. Instruction-level causal chaining records increase the success rate of reproducing multi-level synchronization dependency race conditions involving three or more threads from 50% of existing technologies. The accuracy rate has been improved to 98%, solving the long-standing problem of sporadic and difficult-to-debug race conditions that has plagued developers. A breakthrough improvement in cross-architecture consistency, achieved through semantic equivalence mapping and register state adaptation, increases the consistency of synchronous operation reproduction behavior between x86 and ARM platforms from 85% to 99%, enabling seamless debugging of the same race condition in development environments across different architectures. Timing accuracy reaches the nanosecond level; dynamic calibration based on the instruction latency model reduces the reproduction error of cross-architecture event intervals from microseconds to within 5ns, accurately reproducing fine-grained race conditions with nanosecond-level windows, such as lock contention in high-frequency trading systems. The reproducibility of implicit race conditions is enhanced; the dual-event-driven mechanism of caching and synchronization achieves stable reproduction of implicit race conditions caused by cache visibility for the first time, covering 30% of multi-threaded defect types without explicit synchronization but relying on memory visibility. It boasts strong implementability and controllable overhead; all mechanisms are based on hardware characteristic adaptation and fine-grained event recording, requiring no introduction of intelligent algorithms. Recording overhead only increases by 15% to 20% compared to existing technologies, and replay performance remains at 1 / 5 to 1 / 10 of native execution.
[0227] This invention is not only applicable to traditional desktop and server scenarios, but also meets the multi-threaded debugging needs of embedded systems, providing a unified solution for reproducing race conditions in cross-platform software development.
[0228] In summary, the above are merely preferred embodiments of the present invention and are not intended to limit the scope of protection of the present invention. Any modifications, equivalent substitutions, improvements, etc., made within the spirit and principles of the present invention should be included within the scope of protection of the present invention.
Claims
1. A method for accurately reproducing multi-threaded race conditions for historical debugging, characterized in that, Specifically, the following steps are included: Step 1: Define causal relationship types for multi-threaded synchronization, including release and acquisition, wake-up and execution, and memory visibility; determine multiple system architectures of the target program to be debugged, denoted as target architectures, and establish a semantic equivalence mapping table between synchronization instructions with equivalent semantics under different target architectures, including equivalent semantics, synchronization instructions corresponding to each target architecture, and equivalence judgment conditions; Step 2: Debug and execute the target program in the first target architecture, and record the synchronization events, including user-mode and kernel-mode synchronization operations, including the execution thread ID, synchronization object ID, synchronization operation timestamp, operation type and execution result. The synchronization events have result arrays and cause arrays. Obtain historical events that satisfy the causal conditions with the current synchronized event, form a causal node from the current synchronized event and the historical events, calculate the confidence of the causal node, add it to the result array of the historical events and the cause array of the current synchronized event, and form a bidirectional causal chain from the result array and cause array of all synchronized events. Step 3: Start the replay engine in the second target architecture. Obtain the synchronization object ID, execution thread ID and operation content of the instruction to be executed for the synchronization operation. Query the semantic equivalence mapping table to determine the equivalent semantics. Then, obtain the matching original synchronization event from the bidirectional causal chain. Traverse the cause array of the original synchronization event to obtain the core dependency event and complete the semantic reproduction of the core dependency event. Finally, complete the semantic reproduction of the instruction to be executed based on the record. Semantic reproduction is performed sequentially by traversing the array of results of the original synchronous events and sorting them in descending order of confidence. Until the last instruction to be executed; While recording synchronous events and bidirectional causal chains, the capture and synchronization of cached events are added, including: Step 2.1: In the first target architecture, record cache events including cache line memory address, cache event type, timestamp, original cache state and new cache state. Obtain the cache line with the same memory address as the synchronization object, bind the synchronization event corresponding to the synchronization object to the cache events within a set time before and after the synchronization event, and supplement the binding relationship to the bidirectional causal chain to form an enhanced causal chain. Step 2.2: In the second target architecture, the original synchronization events and related cached events are obtained by matching from the enhanced causal chain based on the synchronization object ID, thread ID, and equivalence semantics; Step 2.3: Reproduce the pre-cache events of the instruction to be executed and synchronize the global virtual cache state; complete the semantic reproduction of the instruction to be executed; reproduce the post-cache events of the instruction to be executed and update the global virtual cache.
2. The method for accurately reproducing multi-threaded race conditions according to claim 1, characterized in that, The causal conditions are: having the same synchronization object as the current synchronization event, ending earlier than the start time of the current synchronization event, being a different thread from the current synchronization event, and having a causal relationship with the current synchronization event.
3. The method for accurately reproducing multi-threaded race conditions according to claim 1, characterized in that, The execution process of semantic reproduction includes: The system performs memory operations to modify the memory according to the execution results of the corresponding synchronization events in the first target architecture, based on the conditional trigger parameters of the recorded instructions. The system maps the recorded status flags to the corresponding status of the second target architecture, inserts the memory barrier instructions corresponding to the second target architecture, and sets the thread status according to the records. For kernel-mode synchronization operations, the system call return value recorded is returned directly, skipping the actual kernel call.
4. The method for accurately reproducing multi-threaded race conditions according to claim 1, characterized in that, While recording synchronization events and bidirectional causal chains, timing data of synchronization command execution is collected, and timing calibration is added during semantic reproduction, including: Step 1.1: Calculate the difference between the start time and end time of the synchronization instruction in the first target architecture as the actual delay; if the actual delay deviates from the preset mean by more than a threshold, update the recorded event delay with the actual delay; otherwise, keep the event delay unchanged; calculate the delay standard deviation for the synchronization instructions executed multiple times. Obtain the time interval between consecutive events in a bidirectional causal chain to form a bidirectional causal chain event containing time-series data, including delay, interval between consecutive events, standard deviation of delay, and time window type; Step 1.2: In the second target architecture, the replay engine obtains the original timing data of the original synchronous event corresponding to the instruction to be executed from the bidirectional causal chain; obtains the event delay of the instruction with equivalent semantics and updates the original timing data; extracts the first original interval between the original synchronous event and the predecessor event, and the second original interval between the original synchronous event and the successor event. When both the first original interval and the second original interval are less than the threshold, if the replay completion timestamp of the predecessor event is less than its sum with the first original interval, then step 1.3 is executed; otherwise, an empty instruction is inserted and the set time is waited before step 1.3 is executed. Step 1.3: Perform semantic reproduction. If the difference between the original event delay and the target architecture delay is greater than the threshold, insert an empty instruction; otherwise, skip the set number of instructions after the instruction to be executed. Step 1.4: For subsequent events, the sum of the actual delay corresponding to the original synchronous event under the second target architecture and the delay of the preceding non-set instruction of the subsequent event is the theoretical interval, and the difference between the second original interval and the theoretical interval is the first time difference that needs to be compensated. If the first time difference is greater than the threshold, a null pointer of the corresponding duration is inserted between the original synchronization event and the subsequent event; otherwise, the non-set instructions are skipped, and the interval between the original target event and the subsequent event is set to the original value.
5. The method for accurately reproducing multi-threaded race conditions according to claim 4, characterized in that, The time window types include fine-grained race condition windows and ordinary time windows.
6. The method for accurately reproducing multi-threaded race conditions according to claim 5, characterized in that, When the original synchronous event belongs to a fine-grained race window, the replay engine assigns original record timestamps to all events within the window, forcing events to be triggered at the locked timestamp; it executes all instructions within the window instruction by instruction, and after each instruction is executed, it calculates the deviation between the current timestamp and the original record timestamp. If the deviation is greater than the first threshold, it inserts an empty instruction to wait.
7. The method for accurately reproducing multi-threaded race conditions according to claim 1, characterized in that, Only retain the complete bidirectional causal chain of the most recent set number of events; for deep bidirectional causal chains exceeding the set number of layers, compress them into an indirect association between the first and last synchronous events, and retain only the summary information of the intermediate nodes.
8. The method for accurately reproducing multi-threaded race conditions according to claim 1, characterized in that, The target architectures are x86 and ARM.
9. The method for accurately reproducing multi-threaded race conditions according to claim 1, characterized in that, Retrieve historical events that satisfy the causal conditions with the current synchronized event. If a historical event is unique, it is considered the predecessor of the current synchronized event and the successor of the historical event. A causal node is formed by the ID of the current synchronized event and the ID of the historical event. The confidence of the causal node is calculated, and the causal node and its confidence are added to the result array of the historical event and the cause array of the current synchronized event. If a historical event is not unique, the causal node with the highest confidence is retained, and its confidence is added to the result array of the corresponding historical event and the cause array of the current synchronized event.
Citation Information
Patent Citations
Target behavior prediction method and related equipment
CN120145203A
Artificial intelligence driven supply chain risk early warning system
CN120875554A