Method and system for debugging programs
By recording the end-to-end flow of business processes during heterogeneous computing debugging, the problem that heterogeneous debugging tools cannot provide full-stack information is solved, improving the efficiency of developers in locating problems and providing an intuitive business process diagram.
Patent Information
- Application Number
- CN201880097908.5
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2018-10-09
- Publication Date
- 2025-11-18
- Estimated Expiration
- 2038-10-09
AI Technical Summary
Current heterogeneous computing debugging tools cannot provide full-stack information, which makes it impossible for developers to perceive the overall business data flow and increases the manpower cost of debugging.
During debugging, the end-to-end flow of the business is recorded. This is achieved by adding a thread identifier field to the function's stack frame and saving the function's stack frame to the stack buffer, thus recording the stack information of the same thread.
It improves the efficiency of developers in locating problems, provides intuitive business process diagrams, and helps developers understand the end-to-end flow of the business.
Smart Images

Figure CN112740187B_ABST
Abstract
Description
Technical Field
[0001] This application relates to the field of computers, and more specifically, to methods and systems for debugging programs in the field of computers. Background Technology
[0002] Currently, heterogeneous computing is emerging as a new form of parallel computing. Depending on the specific business scenario, an increasing number of customized processors have been developed. The emergence of heterogeneous architectures inevitably leads to the need for debugging heterogeneous software. Compute Unified Device Architecture (CUDA)-GDB (GNU debugger) is a tool for running CUDA applications on Linux and Mac. CUDA-GDB is a debugger ported from the x86-64 version of the GDB project released by the GNU open-source organization. This tool provides developers with a mechanism to debug CUDA applications running on actual hardware.
[0003] A CUDA program consists of host-side and device-side code, which run on different devices. For example, host-side code might be compiled and run on an x86 platform, while device-side code might be compiled and run on a graphics processing unit (GPU). During debugging, when a user sets a breakpoint on the host side, and the program hits the host-side breakpoint, the current context includes the host-side stack trace. When a user sets a breakpoint on the device side, and the program hits the device-side breakpoint, the current context only includes the device-side stack trace.
[0004] Therefore, current heterogeneous debugging tools lack the ability to display the full stack. Especially in heterogeneous task linkage, developers cannot perceive the overall business data flow, leading to increased debugging manpower. Summary of the Invention
[0005] This application provides a method and system for debugging programs, which can record the end-to-end flow of business processes during debugging, thereby improving the efficiency of developers in locating problems.
[0006] Firstly, a method for debugging programs is provided, including:
[0007] The first processing module executes the first function of the program being debugged, wherein the stack frame of the first function includes a first identifier, which is used to identify the thread to which the first function belongs;
[0008] When the first function calls the second function, the second processing module executes the second function. The stack frame of the second function includes the first identifier, which is used to identify the thread to which the second function belongs. The second function and the first function belong to the same thread.
[0009] The debugging agent module obtains scheduling information, which is used to instruct the first function to call the second function;
[0010] The debugging agent module sends a notification message to the debugging module, the notification message being used to notify the first function to call the second function;
[0011] The debugging module saves the current first stack frame of the first function to the stack buffer.
[0012] Therefore, this embodiment adds an identifier field to the stack frame of a function to identify the thread to which the function belongs. When the first function running on the first processing module calls the second function, the current stack frame of the first function is saved to the stack buffer, so that the stack frame of the first function saved in the stack buffer is associated with the thread to which the first function belongs, thereby realizing the recording of stack information of the same thread. Based on this, this embodiment can record the end-to-end flow of business during debugging, improving the efficiency of developers in locating problems.
[0013] Optionally, in this embodiment, the first identifier is the thread identifier (thread_ID) of the thread to which the first function and the second function belong.
[0014] In conjunction with the first aspect, some implementations of the first aspect also include:
[0015] After hitting the breakpoint on the second function, obtain the current second stack frame of the second function;
[0016] Obtain the first identifier included in the second stack frame, and obtain the stack frame including the first identifier in the stack buffer.
[0017] Therefore, in this embodiment of the application, when a breakpoint is hit during the debugging process, the stack frame associated with the current thread in the stack buffer can be recorded, thereby providing an intuitive business process diagram, enabling developers to obtain the end-to-end flow of the business during the debugging process and improving the efficiency of developers in locating problems.
[0018] In conjunction with the first aspect, in certain implementations of the first aspect, the debugging module saves the current first stack frame of the first function to the stack buffer, including:
[0019] The debugging module adds the first stack frame to the stack list corresponding to the thread described by the first function in the stack buffer.
[0020] In conjunction with the first aspect, in some implementations of the first aspect, the debugging module saves the current first stack frame of the first function to a stack buffer, including: the debugging module establishing a stack linked list corresponding to the thread of the first function in the stack buffer, wherein the initial node of the stack linked list is the first stack frame.
[0021] In this way, if the stack list corresponding to the thread to which the first function belongs does not exist in the stack buffer, the stack list can be created.
[0022] In conjunction with the first aspect, in some implementations of the first aspect, the first processing module is a host-side processor and the second processing module is a device-side processor.
[0023] In this embodiment, the debugging agent module and the debugging module can be located on a processor, such as a CPU or a GPU. Specifically, the processor can be the processor where the first processing module is located, or the processor where the second processing module is located, or the debugging agent module and the debugging module can be located on a separate processor. This embodiment does not limit this.
[0024] Secondly, a system for debugging is provided for executing the methods described in the first aspect or any possible implementation thereof. Specifically, the system for debugging includes modules for executing the methods described in the first aspect or any possible implementation thereof.
[0025] Thirdly, a computer-readable medium is provided for storing a computer program including instructions for performing the methods in any possible implementation of the first aspect described above.
[0026] Fourthly, a computer program product is provided, the computer program product comprising: computer program code, which, when executed by a processing module or processor in a system of the debugging program, causes the system of the debugging program to perform any possible implementation of the method described in the first aspect. Attached Figure Description
[0027] Figure 1 A schematic diagram of a stack structure is shown.
[0028] Figure 2 A schematic diagram of a heterogeneous debugging framework provided in an embodiment of this application is shown.
[0029] Figure 3A schematic flowchart of a debugging method provided in an embodiment of this application is shown.
[0030] Figure 4 A schematic diagram of a stack structure provided in an embodiment of this application is shown.
[0031] Figure 5 A schematic diagram of a stack buffer provided in an embodiment of this application is shown.
[0032] Figure 6 A schematic diagram of a multi-threaded business flow in the prior art is shown.
[0033] Figure 7 This illustration shows a schematic diagram of a multi-threaded service flow provided in an embodiment of this application.
[0034] Figure 8 An example of a specific debugging procedure provided in an embodiment of this application is shown.
[0035] Figure 9 A schematic flowchart of a method for displaying full-stack information provided in an embodiment of this application is shown.
[0036] Figure 10 An example of a specific debugging procedure provided in an embodiment of this application is shown.
[0037] Figure 11 A schematic block diagram of a debugging program system provided in an embodiment of this application is shown. Detailed Implementation
[0038] The technical solutions in this application will now be described with reference to the accompanying drawings.
[0039] Figure 1 A schematic diagram of a stack structure is shown. (Example) Figure 1 As shown, the upper part of the stack is the stack frame of the main function, and the lower part is the stack frame of the Func(function)1 function, which is the stack frame of the current function (the callee). The bottom of the stack is at a high address, and the stack grows downwards. A stack frame is a portion of the stack space allocated separately for a function call. For example, when a running program calls another function, it enters a new stack frame. The original function's stack frame is called the caller's frame, and the new stack frame is called the current frame. After the called function finishes executing, the current frame collapses completely, returning to the caller's frame.
[0040] Specifically, the main function's stack frame includes registers pushed onto the stack, function parameters, local variables, and the parameters of the calling function. The Func1 function's stack frame also includes registers pushed onto the stack, function parameters, local variables, and the parameters of the calling function. Registers are used to record important information about the currently running function; for example, when entering a new function, the registers store information from the previous function. Registers include, for example, the program counter (PC) register, the link register (LR), the stack pointer (SP) register, and the frame pointer (FP) register. FP points to the bottom of the current function's stack frame, and SP points to the top of the current function's stack frame.
[0041] When a function call occurs, the system performs stack context saving: First, the relevant registers are pushed onto the stack; then, the function's input parameters are pushed onto the stack, the function's local variables are pushed onto the stack, and finally, the parameters of the called function are pushed onto the stack. Here, pushing means putting data onto the stack from the top, and popping data means retrieving it from the top of the stack.
[0042] Figure 2 A schematic diagram of a heterogeneous debugging framework 200 provided in an embodiment of this application is shown. Figure 2 As shown, the framework for heterogeneous debugging mainly includes a debugging module 201, a debugging agent module 202, and a stack buffer 203.
[0043] Debugging Module 201: A module for direct interaction between developers, providing basic debugging capabilities and responsible for communicating with the debugging agent module 202 to issue debugging commands.
[0044] Debugging agent module 202: Shields the differences in underlying hardware, provides a unified debugging interface, and enables information collection and device control of the underlying hardware. Here, the underlying hardware may include, for example, a central processing unit (CPU) 204, a graphics processing unit (GPU) 205, and a many-core processor 206.
[0045] In this embodiment, CPU 204 can be a host-side processor, and GPU 205 and many-core processor 206 can be device-side processors. Here, device can be, for example, an application-specific integrated circuit (ASIC), but this embodiment does not limit it.
[0046] Stack buffer 203: A specific memory block allocated in double data rate SDRAM (DDR) carries and stores global stack information of heterogeneous processors in this embodiment. As an example, the stack buffer 203 may include stack frame 0, stack frame 1, and stack frame 2.
[0047] It should be noted that, in this embodiment, the stack buffer 203 is only described as being located in DDR. It is understood that the stack buffer 203 can also be located in other storage structures or memories, such as high-bandwidth memory (HBM) or hybrid memory cube (HMC). This embodiment does not limit its use in this regard. Furthermore, in this embodiment, the stack buffer can also have other names, such as a global stack buffer. This embodiment does not limit its use in this regard.
[0048] Figure 3 A schematic flowchart illustrating a method for debugging a program according to an embodiment of this application is shown. As an example, this method can be... Figure 2 The heterogeneous debugging framework 200 is executed in the present application, but this embodiment does not limit it.
[0049] 310. The first processing module executes a first function of the program being debugged, wherein the stack of the first function includes a first identifier, which is used to identify the thread to which the first function belongs. For example, the thread to which the first function belongs may be the first thread.
[0050] Here, the first processing module is a host-side device or a device-side device. Specifically, it can be a CPU, GPU, many-core processor, or ASIC as mentioned above, but this application embodiment does not limit this.
[0051] Specifically, the process being debugged may include at least one thread, such as a first thread. Optionally, the process being debugged may also include a second thread, but this application embodiment does not limit this.
[0052] Optionally, the first identifier can be the thread identifier (thread_ID) of the thread described in the first function. In this embodiment, in the original function (e.g., the main function and the function called by the main function), for example... Figure 1 In the stack structure shown, a thread identifier field for the thread to which the function belongs can be added. Specifically, in this embodiment, when a stack frame is created, the thread_ID can be written as a field into the stack structure as a unique identifier for the stack chain structure.
[0053] Optionally, the thread_ID field can be passed down from the host side to identify the thread to which the stack frame of the currently running function belongs.
[0054] Figure 4 A schematic diagram of a stack structure provided in an embodiment of this application is shown. Figure 4 As shown, a new thread ID (thread_ID) field has been added to the main function's stack frame, indicating that the thread ID to which the main function's stack frame belongs is thread_ID. A new thread_ID field has also been added to the Func1 function's stack frame, indicating that the thread ID to which the Func1 function's stack frame belongs is also thread_ID.
[0055] 320. When the first function calls the second function, the second processing module executes the second function.
[0056] In this implementation, the stack frame of the second function includes the first identifier, which is used to identify the thread described by the second function; that is, the first identifier is used to identify that the second function and the first function belong to the same thread. In one implementation, the first identifier can be passed from the first processing module to the second processing module.
[0057] In one possible implementation, the first processing module is a CPU, the first function is the main function, the second processing module is a GPU or a multi-core processor, and the second function is a function called by the main function.
[0058] In another possible implementation, the first processing module can be a GPU or a multi-core processor, the second processing module can be a GPU or a multi-core processor different from the first processing module, and the second function can be a function called by the first function.
[0059] 330. The debugging agent module obtains scheduling information, which is used to instruct the first function to call the second function.
[0060] Specifically, when inter-core scheduling occurs, the scheduling framework of the program being debugged will send the task scheduling to the debug agent module 202, and the information related to the task scheduling can be included in the aforementioned scheduling information.
[0061] 340. The debug proxy module sends a first notification message to the debug module. This first notification message is used to notify the debug module that the first function calls the second function. Specifically, after receiving the scheduling information sent by the scheduling framework in 330, the debug proxy module 202 sends a signal to the debug module 201 to notify the inter-core scheduling.
[0062] In this embodiment, the debugging agent module and the debugging module can be located on a processor, such as a CPU or a GPU. Specifically, the processor can be the processor where the first processing module is located, or the processor where the second processing module is located, or the debugging agent module and the debugging module can be located on a separate processor. This embodiment does not limit this.
[0063] 350, the debugging module saves the current first stack frame of the first function to the stack buffer.
[0064] In this embodiment, the debugging module 201 then saves the current device's stack frame to the stack buffer 203 according to the original format of the stack frame.
[0065] Optionally, in one implementation, when the stack buffer 203 contains a stack list corresponding to the thread to which the first function belongs (e.g., the first thread), the debug module 201 adds the first stack frame to the stack list of the first thread.
[0066] Alternatively, in another implementation, when the stack buffer 203 does not contain the stack list of the first thread, the debugging module 201 creates the stack list of the first thread in the stack buffer, and the initial node of the stack list of the first thread is the first stack frame.
[0067] Specifically, if the current stack buffer 203 does not have a stack list corresponding to the thread_id of the stack frame that needs to be saved, a new stack list is created, and the current stack frame is added to the list as an initial node. If the current stack buffer 203 already has a stack list corresponding to the thread_id of the stack frame that needs to be saved, the current processor's stack frame is added to the stack list corresponding to that thread_id.
[0068] As stack frame insertions continue to occur, for example, stack buffer 203 can take the form of: Figure 5 As shown. Specifically, the stack buffer 203 contains three stack lists for threads, identified as thread 0, thread 1, and thread 2. The stack list labeled thread_0 includes the host stack frame, ASIC0 stack frame, ASIC4 stack frame, and ASIC8 stack frame; the stack list labeled thread_1 includes the host stack frame, ASIC1 stack frame, ASIC6 stack frame, and ASIC9 stack frame; and the stack list labeled thread_2 includes the host stack frame, ASIC3 stack frame, ASIC7 stack frame, ASIC2 stack frame, and ASIC5 stack frame.
[0069] Therefore, this embodiment adds an identifier field to the stack frame of a function to identify the thread to which the function belongs. When the first function running on the first processing module calls the second function, the current stack frame of the first function is saved to the stack buffer, so that the stack frame of the first function saved in the stack buffer is associated with the thread to which the first function belongs, thereby realizing the recording of stack information of the same thread. Based on this, this embodiment can record the end-to-end flow of business during debugging, improving the efficiency of developers in locating problems.
[0070] Optionally, in this embodiment of the application, after hitting the breakpoint on the second function, the current second stack frame of the second function is obtained, and then the second stack frame is parsed to obtain the first identifier included in the second stack frame. Then, the stack frame including the first identifier can be obtained from the stack buffer.
[0071] Specifically, after hitting a pre-set breakpoint, the user's command to display stack information can be obtained. At this time, the stack frame of the current processing module (e.g., the second processing module) can be displayed first. Then, based on the thread_id information of the current stack frame, the corresponding stack list of thread_id can be found in the stack buffer. Then, the stack frames in the stack list are displayed one by one, thereby obtaining the full stack information from the start of the program to the current state.
[0072] Similarly, a similar operation can be performed on the second thread of the debugged program according to the descriptions in steps 310 to 350. When the user performs a core switching operation and displays the stack of the second thread, the complete full stack information of the second thread will be displayed according to the process described above, thereby achieving the purpose of full stack display.
[0073] Therefore, in this embodiment of the application, when a breakpoint is hit during the debugging process, the stack frame associated with the current thread in the stack buffer can be recorded, thereby providing an intuitive business process diagram, enabling developers to obtain the end-to-end flow of the business during the debugging process and improving the efficiency of developers in locating problems.
[0074] In addition, in this embodiment, the previously messy but internally related inter-core stack information can be organized into a tree structure to provide a more intuitive data flow diagram. Figure 6 A schematic diagram of a multi-threaded business flow in the prior art is shown. Figure 6The diagram displays three service flow information sets: a dashed line indicating the flow from host->ASIC 0->ASIC 4->ASIC 8; a solid line indicating the flow from host->ASIC 1->ASIC 6->ASIC 9; and a dotted line indicating the flow from host->ASIC 3->ASIC 7->ASIC 2->ASIC 5. Because current debugging techniques do not focus on the inter-core call relationships during service execution, users cannot intuitively obtain the call relationships between processors; they can only obtain the stack frames on a specific core. For example, when a breakpoint is hit on ASIC 8, only the stack frames on ASIC 8 can be obtained, but the service flow information from host->ASIC 0->ASIC 4->ASIC 8 cannot be retrieved.
[0075] Figure 7 A schematic diagram of a multi-threaded service flow provided in an embodiment of this application is shown. Figure 7 As shown in the embodiments of this application, when a breakpoint is hit during program debugging, the stack associated with the current thread in the stack buffer can be displayed. For example, when a breakpoint on ASIC 8 is hit, not only can the stack information on ASIC 8 be obtained, but also the business flow information from host->ASIC 0->ASIC 4->ASIC 8 can be obtained. When a core switch occurs, the business flow information from host->ASIC 1->ASIC 6->ASIC 9 and from host->ASIC 3->ASIC 7->ASIC 2->ASIC 5 can also be displayed. Thus, the embodiments of this application can provide an intuitive business flow diagram, enabling developers to obtain the end-to-end flow of the business during debugging and improving the efficiency of developers in locating problems.
[0076] Figure 8 An example of a specific debugging procedure provided in an embodiment of this application is shown. It should be understood that... Figure 8 The steps or operations for debugging a program are illustrated, but these steps or operations are merely examples, and other operations may be performed in the embodiments of this application. Figure 8 Variations of various operations within it. Furthermore... Figure 8 The various steps in can be followed according to Figure 8 The different orders in which they are presented may be executed, and it is possible that they are not intended to be executed. Figure 8 All operations within.
[0077] In this embodiment of the application, the code of the program being debugged is mainly divided into the following three parts:
[0078] The main function is the code on the host side, and it is compiled and run on the host side.
[0079] The asic0_fun function is device-side code, compiled and run on the ASIC 0 side;
[0080] The asic1_fun function is for the device side, and is compiled and run on the ASIC 1 side.
[0081] As an example, the program being debugged is shown below:
[0082]
[0083]
[0084] 801, Start the program being debugged.
[0085] Specifically, the debugging module establishes a debugging agent process and identifies the process to be debugged. As an example, the debugging module sets breakpoints in the code on the ASIC1 side. Then, the debugging module can send a start-debug command to the CPU through the debugging agent module.
[0086] 802, the CPU executes the main function.
[0087] Specifically, during the execution of the process being debugged, the host program is executed first. Assume that the thread_id running at this point is 0. At this time, the stack frame of the main function includes the identifier thread_0.
[0088] 803, the main function calls the asic0_func function on ASIC0.
[0089] Specifically, during the execution of the program on the host side, the main function calls the asic0_fun function to execute the business logic on the ASIC0 side. At this time, the scheduling framework of the program being debugged sends the task scheduling to the debug agent module.
[0090] 804, the debug agent module notifies the debug module of inter-core scheduling.
[0091] After receiving this information, the debugging agent module sends a signal to the debugging module to notify the main function of the debugging module to schedule the asic0_func function.
[0092] 805, the debug module saves the current CPU stack frame.
[0093] After receiving the signal from the debug agent module, the debug module confirms that it is a task scheduling signal and then saves the current device's stack information. Specifically, the debug module saves the current stack frame of the CPU's main function.
[0094] This is the first time a stack frame is stored in the stack buffer. The current stack buffer does not have a stack list corresponding to the thread_id 0 of the stack frame that needs to be saved. Therefore, a new stack list needs to be created, and the stack frame of the current main function is added to the list as an initial node. As an example, this stack frame can be labeled as stack frame 0. The information in this stack frame is int main()at xxx.cce:10.
[0095] 806, ASIC 0 executes the asic0_func function, and the business logic continues to execute on ASIC 0.
[0096] 807, the asic0_func function calls the asic1_func function on ASIC1.
[0097] 808, the debug agent module notifies the debug module of inter-core scheduling.
[0098] Similarly, the debugging agent module needs to notify the debugging module via a signal to schedule the asic0_func function to schedule the asic1_func function.
[0099] 809, the debug module saves the current stack frame of ASIC 0.
[0100] Specifically, the debugging module adds the current stack frame of ASIC 0 to the stack list. More specifically, when adding the current stack frame of the asic1_func function on ASIC 1 to the stack list, the current stack frame of ASIC 0 is added to the stack with thread_id 0, which is the list containing stack_main. As an example, this newly added stack frame can be represented as stack frame 1, and the information in this stack frame is void asic0_fun()at xxx.cce:6.
[0101] Therefore, this embodiment adds an identifier field to the stack frame of a function to identify the thread to which the function belongs. When the first function running on the first processing module calls the second function on the second device, the current stack frame of the first function is saved to the stack buffer, so that the stack frame of the first function saved in the stack buffer is associated with the thread to which the first function belongs, thereby realizing the recording of stack information of the same thread. Based on this, this embodiment can record the end-to-end flow of business during debugging, improving the efficiency of developers in locating problems.
[0102] Figure 9 A schematic flowchart illustrating a method for displaying full-stack information according to an embodiment of this application is shown. It should be understood that... Figure 9The steps or operations for displaying full-stack information are illustrated, but these steps or operations are merely examples, and other operations may be performed in the embodiments of this application. Figure 9 Variations of various operations within it. Furthermore... Figure 9 The various steps in can be followed according to Figure 9 The different orders in which they are presented may be executed, and it is possible that they are not intended to be executed. Figure 9 All operations within.
[0103] Figure 9 Zhongyu Figure 8 The same modules or units have the same or similar meanings, and for the sake of brevity, they will not be described here.
[0104] 901, a breakpoint on ASIC 1 was hit.
[0105] 902. Following 901, ASIC 1 can report breakpoint events to the debug module.
[0106] 903 is the debug module's call to the backtrace command. Specifically, 903 can be divided into three parts: 9031, 9032, and 9033.
[0107] Specifically, after hitting the breakpoint, the user can return to the debugging interface. When the user displays the stack trace using the `backtrace` command, 9031 is executed first to display the stack frame on ASIC1. For example, the stack frame on ASIC1 is `void asic1_fun()at xxx.cce:2`. Then, 9032 is executed to obtain the identifier `thread_id` on the stack frame of ASIC1. Specifically, in this embodiment, `thread_id` is `thread_0`. Then, the stack list of `thread_0` is searched in the stack buffer. At this point, the stack list of `thread_0` can be found in the stack buffer. In this embodiment, the stack list includes `stack frame_0` and `stack frame_1`. For example, the list can be output in reverse order to obtain the full stack information from ASIC1 -> ASIC0 -> host, as shown below:
[0108]
[0109] Therefore, in this embodiment of the application, when a breakpoint is hit during the debugging process, the stack frame associated with the current thread in the stack buffer can be recorded, thereby providing an intuitive business process diagram, enabling developers to obtain the end-to-end flow of the business during the debugging process and improving the efficiency of developers in locating problems.
[0110] In another embodiment of this application, if the host side is a multi-threaded program, assuming the user creates two threads to perform business processing respectively, these two threads are, for example, thread 0 (thread_0) and thread 1 (thread_1), and the user sets a breakpoint on ASIC2 of thread_0. Meanwhile, the business processing on ASIC4 of thread_1 takes a long time, and when the breakpoint on ASIC2 is hit, ASIC4 will still perform business processing.
[0111] When thread_0 is scheduled to ASIC 0, as described above, the host-side stack frame of thread_0 will be added to the global stack buffer, and a new stack list with thread_0 as the key will be created.
[0112] When thread_1 is scheduled to ASIC 3, the host-side stack frame of thread_1 is added to the global stack buffer, and a new stack list with thread_1 as the key is created.
[0113] When thread_0 is scheduled to ASIC 1, the stack frame of ASIC 0 needs to be pushed onto the stack. At this time, since the stack list corresponding to thread_0 already exists in the stack buffer, the stack frame of ASIC 0 is added to the stack list corresponding to thread_0.
[0114] When thread_1 is scheduled to ASIC 4, the stack frame of ASIC 3 needs to be pushed onto the stack. At this time, since the stack list corresponding to thread_1 already exists in the stack buffer, the stack frame of ASIC 3 is added to the stack list corresponding to thread_1.
[0115] When thread_0 is scheduled to ASIC 2, the stack of ASIC 1 is added to the stack list corresponding to thread_0. When ASIC 2 hits an interrupt point, the current stack buffer is as follows: Figure 10 As shown, thread_0 contains the stack frames of host / ASIC 0 / ASIC 1 and preserves their calling order, while thread_1 contains the stack frame of host / ASIC 3.
[0116] Therefore, this application embodiment adds an identifier field to the stack frame of a function to identify the thread to which the function belongs. When the first function on the first processing module calls the second function, the current stack frame of the first function is saved to the stack buffer, so that the stack frame of the first function saved in the stack buffer is associated with the thread to which the first function belongs, thereby realizing the recording of stack information of the same thread. Based on this, this application embodiment can record the end-to-end flow of business during debugging, improving the efficiency of developers in locating problems.
[0117] In this embodiment, when a breakpoint is hit on the ASIC 2, the user views the current stack frame using the backtrace command. First, the stack frame on the ASIC 2 device is obtained. When parsing the thread_id field in the ASIC 2 stack frame, this embodiment shows that the thread_id is thread_0. Then, the stack of thread_0 is searched in the stack buffer. Since a stack list for thread_0 exists in the stack buffer, this stack list is parsed sequentially to obtain all the stack information, as shown below:
[0118]
[0119] If the user performs a core switching operation at this time, such as switching to ASIC 4, when viewing the current stack frame using the backtrace command, the stack information on ASIC 4 is first obtained. If the thread_id field in the ASIC 4 stack frame is thread_1, the stack with thread_id thread_1 is searched in the stack buffer. Since the stack buffer contains a linked list of thread_1 stacks, this linked list is parsed sequentially to obtain the full stack information, which is as follows:
[0120]
[0121] Therefore, in this embodiment of the application, when a breakpoint is hit during the debugging process, the stack frame associated with the current thread in the stack buffer can be recorded, thereby providing an intuitive business process diagram, enabling developers to obtain the end-to-end flow of the business during the debugging process and improving the efficiency of developers in locating problems.
[0122] Figure 11 A schematic diagram of a debugging program system 1100 provided in an embodiment of this application is shown. The system 1100 includes a first processing module 1110, a second processing module 1120, a debugging agent module 1130, a debugging module 1140, and a stack buffer 1150.
[0123] The first processing module 1100 is used to execute a first function of the program being debugged, wherein the stack frame of the first function includes a first identifier, which is used to identify the thread to which the first function belongs.
[0124] When the first function running on the first processing module 1100 calls the second function, the second processing module 1120 executes the second function. The stack frame of the second function includes the first identifier, which is used to identify the thread to which the second function belongs. The second function and the first function belong to the same thread.
[0125] The debugging agent module 1130 is used to obtain scheduling information, which is used to instruct the first function to call the second function;
[0126] The debugging agent module 1130 is also used to send a notification message to the debugging module 1140, the notification message being used to notify the first function to call the second function;
[0127] The debugging module 1140 is used to save the current first stack frame of the first function to the stack buffer 1150.
[0128] Therefore, this embodiment adds an identifier field to the stack frame of a function to identify the thread to which the function belongs. When the first function running on the first processing module calls the second function, the current stack frame of the first function is saved to the stack buffer, so that the stack frame of the first function saved in the stack buffer is associated with the thread to which the first function belongs, thereby realizing the recording of stack information of the same thread. Based on this, this embodiment can record the end-to-end flow of business during debugging, improving the efficiency of developers in locating problems.
[0129] Optionally, the system 1100 of the debugger also includes an acquisition module for:
[0130] After hitting the breakpoint on the second function, obtain the current second stack frame of the second function;
[0131] Obtain the first identifier included in the second stack frame, and obtain the stack frame including the first identifier in the stack buffer.
[0132] Therefore, in this embodiment of the application, when a breakpoint is hit during the debugging process, the stack frame associated with the current thread in the stack buffer can be recorded, thereby providing an intuitive business process diagram, enabling developers to obtain the end-to-end flow of the business during the debugging process and improving the efficiency of developers in locating problems.
[0133] Optionally, the debugging module 1140 is specifically used for:
[0134] Add the first stack frame to the stack list of the thread to which the first function belongs in the stack buffer.
[0135] Optionally, the debugging module 1140 is specifically used for:
[0136] A stack list corresponding to the thread to which the first function belongs is established in the stack buffer, and the initial node of the stack list is the first stack frame.
[0137] Optionally, the first processing module 1110 is a host-side processor, and the second processing module 1120 is a device-side processor.
[0138] Figure 11 The debugging program system 1100 shown can implement the various processes corresponding to the aforementioned method embodiments. Specifically, the various modules in the debugging program system 1100 can be referred to the description above, and will not be repeated here to avoid repetition.
[0139] This application also provides a computer-readable medium for storing a computer program, the computer program including instructions for performing the above-described debugging program.
[0140] This application also provides a computer program product, which includes computer program code. When the computer program code is run by a processing module or processor in the system of the debugging program, the system of the debugging program executes the method of the debugging program described above.
[0141] It should be understood that the processor mentioned in the embodiments of the present invention can be a CPU, or other general-purpose processors, digital signal processors (DSPs), application-specific integrated circuits (ASICs), field-programmable gate arrays (FPGAs), or other programmable logic devices, discrete gate or transistor logic devices, discrete hardware components, etc. The general-purpose processor can be a microprocessor or any conventional processor.
[0142] It should also be understood that the memory or storage module mentioned in the embodiments of the present invention can be volatile memory or non-volatile memory, or may include both volatile and non-volatile memory. The non-volatile memory can be read-only memory (ROM), programmable read-only memory (PROM), erasable programmable read-only memory (EPROM), electrically erasable programmable read-only memory (EEPROM), or flash memory. The volatile memory can be random access memory (RAM), which is used as an external cache. By way of example, but not limitation, many forms of RAM are available, such as Static RAM (SRAM), Dynamic RAM (DRAM), Synchronous DRAM (SDRAM), Double Data Rate SDRAM (DDR SDRAM), Enhanced Synchronous DRAM (ESDRAM), Synchlink DRAM (SLDRAM), and Direct Rambus RAM (DR RAM).
[0143] It should be noted that when the processor is a general-purpose processor, DSP, ASIC, FPGA, or other programmable logic device, discrete gate or transistor logic device, or discrete hardware component, the memory (storage module) is integrated into the processor.
[0144] It should be understood that the descriptions of "first", "second", etc. appearing in the embodiments of this application are only for illustration and to distinguish the objects being described, and there is no order to them. They do not indicate any special limitation on the number of devices in the embodiments of this application, and cannot constitute any limitation on the embodiments of this application.
[0145] It should also be understood that, in the various embodiments of this application, the order of the above-mentioned processes does not imply the order of execution. The execution order of each process should be determined by its function and internal logic, and should not constitute any limitation on the implementation process of the embodiments of this application.
[0146] Those skilled in the art will recognize that the units and algorithm steps of the various examples described in conjunction with the embodiments disclosed herein can be implemented in electronic hardware, or a combination of computer software and electronic hardware. Whether these functions are implemented in hardware or software depends on the specific application and design constraints of the technical solution. Those skilled in the art can use different methods to implement the described functions for each specific application, but such implementation should not be considered beyond the scope of this application.
[0147] Those skilled in the art will understand that, for the sake of convenience and brevity, the specific working processes of the systems, devices, and units described above can be referred to the corresponding processes in the foregoing method embodiments, and will not be repeated here.
[0148] In the several embodiments provided in this application, it should be understood that the disclosed systems, apparatuses, and methods can be implemented in other ways. For example, the apparatus embodiments described above are merely illustrative; for instance, the division of units is only a logical functional division, and in actual implementation, there may be other division methods. For example, multiple units or components may be combined or integrated into another system, or some features may be ignored or not executed. Furthermore, the coupling or direct coupling or communication connection shown or discussed may be through some interfaces; the indirect coupling or communication connection between apparatuses or units may be electrical, mechanical, or other forms.
[0149] The units described as separate components may or may not be physically separate. The components shown as units may or may not be physical units; that is, they may be located in one place or distributed across multiple network units. Some or all of the units can be selected to achieve the purpose of this embodiment according to actual needs.
[0150] In addition, the functional units in the various embodiments of this application can be integrated into one processing unit, or each unit can exist physically separately, or two or more units can be integrated into one unit.
[0151] If the aforementioned functions are implemented as software functional units and sold or used as independent products, they can be stored in a computer-readable storage medium. Based on this understanding, the technical solution of this application, in essence, or the part that contributes to the prior art, or a portion of the technical solution, can be embodied in the form of a software product. This computer software product is stored in a storage medium and includes several instructions to cause a computer device (which may be a personal computer, server, or network device, etc.) to execute all or part of the steps of the methods described in the various embodiments of this application. The aforementioned storage medium includes various media capable of storing program code, such as USB flash drives, portable hard drives, read-only memory (ROM), random access memory (RAM), magnetic disks, or optical disks.
[0152] The above description is merely a specific embodiment of this application, but the scope of protection of this application is not limited thereto. Any variations or substitutions that can be easily conceived by those skilled in the art within the scope of the technology disclosed in this application should be included within the scope of protection of this application. Therefore, the scope of protection of this application should be determined by the scope of the claims.
Claims
1. A method for debugging a program, characterized in that, include: The first processing module executes the first function of the program being debugged, wherein the stack frame of the first function includes a first identifier, which is used to identify the thread to which the first function belongs; When the first function calls the second function, the second processing module executes the second function. The stack frame of the second function includes the first identifier, which is used to identify the thread to which the second function belongs. The second function and the first function belong to the same thread. The debugging agent module obtains scheduling information, which is used to instruct the first function to call the second function; The debugging agent module sends a notification message to the debugging module, the notification message being used to notify the first function to call the second function; The debugging module saves the current first stack frame of the first function to the stack buffer; The first processing module is a host-side processor, and the second processing module is a device-side processor.
2. The method according to claim 1, characterized in that, Also includes: After hitting the breakpoint on the second function, obtain the current second stack frame of the second function; Obtain the first identifier included in the second stack frame, and obtain the stack frame including the first identifier in the stack buffer.
3. The method according to claim 1 or 2, characterized in that, The debugging module saves the current first stack frame of the first function to the stack buffer, including: The debugging module adds the first stack frame to the stack list corresponding to the thread to which the first function belongs in the stack buffer.
4. The method according to claim 1 or 2, characterized in that, The debugging module saves the current first stack frame of the first function to the stack buffer, including: The debugging module establishes a stack list in the stack buffer corresponding to the thread to which the first function belongs, and the initial node of the stack list is the first stack frame.
5. A system for debugging programs, characterized in that, include: The first processing module is used to execute the first function of the program being debugged, wherein the stack frame of the first function includes a first identifier, which is used to identify the thread to which the first function belongs; When the first function running on the first processing module calls the second function, the second processing module is used to execute the second function. The stack frame of the second function includes the first identifier, which is used to identify the thread to which the second function belongs, wherein the second function and the first function belong to the same thread. A debugging agent module is used to obtain scheduling information, which is used to instruct the first function to call the second function; The debugging agent module is also used to send a notification message to the debugging module, the notification message being used to notify the first function to call the second function; The debugging module is used to save the current first stack frame of the first function to the stack buffer; The first processing module is a host-side processor, and the second processing module is a device-side processor.
6. The system according to claim 5, characterized in that, It also includes an acquisition module, used for: After hitting the breakpoint on the second function, obtain the current second stack frame of the second function; Obtain the first identifier included in the second stack frame, and obtain the stack frame including the first identifier in the stack buffer.
7. The system according to claim 5 or 6, characterized in that, The debugging module is specifically used for: Add the first stack frame to the stack list of the thread to which the first function belongs in the stack buffer.
8. The system according to claim 5 or 6, characterized in that, The debugging module is specifically used for: A stack list corresponding to the thread to which the first function belongs is established in the stack buffer, and the initial node of the stack list is the first stack frame.
Citation Information
Patent Citations
Method for realizing debugging of single function by user state debugger and system thereof
CN101446918A
Program debugging method and device
CN104252402A