Method for testing computer program
By setting breakpoints in embedded systems and detecting the directionality of memory access instructions through debugger control, the problem of Sanitizer's high resource consumption in embedded systems is solved, and effective testing and error display of undefined behavior is achieved. , suitable for resource-constrained embedded systems.
Patent Information
- Application Number
- CN202410856037.8
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Priority Date
- 2023-06-30
- Filing Date
- 2024-06-28
- Publication Date
- 2024-12-31
AI Technical Summary
Existing Sanitizer tools are difficult to use in embedded systems, consume high resources and may affect the execution of computer programs, resulting in undefined behavior errors not being discovered.
By setting breakpoints in a computer program, the memory access instructions are detected by debugger control, and if they are not directed, an error display will be triggered, which will realize the testing of undefined behavior, avoiding the resource consumption of Sanitizer and instrumentation or emulator dependency.
Effectively detect and display errors in computer programs on embedded systems, improve the ability to test undefined behaviors, and is suitable for embedded systems with resource-constrained, avoiding the impact of Sanitizer on execution.
Smart Images

Figure CN119226132A_ABST
Abstract
Description
Technical Field
[0001] The present disclosure relates to a method for testing a computer program. Background Art
[0002] An important part of developing software applications is testing and the corresponding error clearing when errors are found. In particular, errors that lead to application failures should be identified and corrected. An important aspect here is testing for undefined behavior, such as by so-called (memory) sanitizers. Compiling and testing software on common desktop and server hardware, such as x86, with the help of various sanitizers is a measure that can discover errors such as the Heartbleed bug that previously remained undiscovered for a long time.
[0003] Comprehensive testing is particularly important for computer programs on often safety-relevant embedded systems, such as control devices for vehicles. However, sanitizers for desktop and server hardware cannot be used or can only be used poorly for such systems, since embedded systems typically have restricted resources and such sanitizers have a huge resource requirement and therefore cannot be used or can even affect the execution of the computer program so that errors occur in the first place or remain undetected. Summary of the invention
[0004] Therefore, a method for testing a computer program that can implement testing for undefined behaviors and is applicable to embedded systems is desirable.
[0005] According to various embodiments, a method for (automatically) testing a computer program is provided, the method comprising: setting one or more breakpoints in the computer program to one or more memory access instructions; executing the computer program; upon triggering one of the set breakpoints, determining whether the memory access instruction is used to access a data element having a size required for a storage address oriented to the data element to be written to or from which the data element is read, and determining the required orientation if necessary; if the memory access instruction is used to access a data element having a size required for a storage address oriented to the data element to be written to or from which the data element is read, determining whether the storage address accessed by the memory access instruction satisfies the required orientation; and in response to determining that the storage address accessed by the memory access instruction does not satisfy the required orientation, triggering a display that the computer program has an error.
[0006] This can be done for each or at least a plurality of memory access instructions occurring in the computer program (eg depending on how many breakpoints are available).
[0007] The above method enables testing on embedded systems with the aid of a debugger using detection of lack of orientation. This is particularly applicable when testing with fuzz testing, since fuzz testing can also be implemented in a debugger-controlled manner and in this way can be effectively used on embedded systems.
[0008] Sanitizers can be implemented with the aid of code instrumentation. However, for this purpose either the source code must be available or command set-specific instrumentation based on binaries (binary instrumentation) is required, which is very susceptible. The alternative emulator-based instrumentation is also very platform-specific, and each embedded platform requires its own emulator. The method described above enables testing with a debugger-controlled sanitizer without the need for instrumentation or emulation, and can therefore be applied in many cases.
[0009] Various embodiments are described below.
[0010] Embodiment 1 is a method for testing a computer program as described above.
[0011] Embodiment 2 is a method according to embodiment 1, comprising: in response to determining that the storage address accessed by the memory access instruction does not satisfy the required orientation, triggering a display that the computer program has an error by triggering the termination (ie, crash) of the computer program.
[0012] Thus, for example, within the scope of fuzz testing, a computer program can be marked as having an error, because its execution causes the computer program to terminate (i.e. crash), after which the fuzzer displays an error. For example, a warning can also be output on the stderr stream, or a debugger can be monitored on the host side (i.e. on a test system that tests the computer program on the execution system with the aid of a debugger).
[0013] Embodiment 3 is a method according to embodiment 1 or 2, comprising: determining whether a memory access instruction is used to access a data element having a size required for orientation to a storage address to which the data element is written or from which the data element is read by one or more of an evaluation of an opcode of the memory access instruction, an evaluation of execution information by a debugger, a result of a static analysis of a computer program, and information about the architecture of a system on which the computer program is executed, and determining the required orientation when necessary.
[0014] It is thereby possible to determine for various types of memory access instructions and architectures whether a memory access instruction is used to access a data element having a size required for orientation to the memory address to which the data element is written or from which the data element is read, and if necessary, the required orientation.
[0015] Embodiment 4 is a method according to any one of embodiments 1 to 3, comprising executing multiple test passes (eg, fuzzy test passes, i.e., fuzzy test iterations) and setting breakpoints to different memory access instructions for different test passes.
[0016] This allows a large number of memory access instructions to be covered.
[0017] Embodiment 5 is a method according to any one of embodiments 1 to 4, comprising: executing a computer program on an embedded system and performing the following steps through a test system connected to the embedded system (via a debugging interface): setting breakpoints, determining whether a memory access instruction requires orientation, determining the required orientation if necessary, determining whether the memory access instruction satisfies the orientation if necessary, and triggering a display if necessary: the computer program has an error.
[0018] According to various embodiments, in particular, testing of a computer program for an embedded system, including memory monitoring, is enabled on the embedded system itself.
[0019] Embodiment 6 is a method according to any one of embodiments 1 to 5, wherein the computer program is a control program for a robotic device, and the robotic device is controlled using the computer program based on a result of a test of the computer program.
[0020] Embodiment 7 is a testing device configured to perform the method according to any one of embodiments 1 to 6.
[0021] Embodiment 8 is a computer program having instructions, which, when executed by a processor, cause the processor to perform the method according to any one of embodiments 1 to 6.
[0022] Embodiment 9 is a computer-readable medium storing instructions, and when the instructions are executed by a processor, the instructions cause the processor to perform the method according to any one of embodiments 1 to 6. BRIEF DESCRIPTION OF THE DRAWINGS
[0023] In the accompanying drawings, similar reference numerals generally refer to the same parts throughout the various views. The accompanying drawings are not necessarily drawn to scale, with emphasis instead generally being placed on illustrating the principles of the invention. In the following description, various aspects are described with reference to the following drawings.
[0024] Figure 1 A computer used to develop and / or test software applications is shown.
[0025] Figure 2 A flow chart is shown which illustrates a method for testing a computer program according to one embodiment. DETAILED DESCRIPTION
[0026] The following detailed description relates to the attached drawings, which illustrate specific details and aspects of the present disclosure that can perform the present invention for the purpose of illustration. Other aspects may be used and structural, logical and electrical changes may be made without departing from the scope of protection of the present invention. Various aspects of the present disclosure are not necessarily mutually exclusive, because some aspects of the present disclosure may be combined with one or more other aspects of the present disclosure to form new aspects.
[0027] Various examples are described in more detail below.
[0028] Figure 1 A computer 100 is shown for use in developing and / or testing software applications.
[0029] The computer 100 has a CPU (Central Processing Unit) 101 and a work memory (RAM) 102. The work memory 102 is used to load a program code from a hard disk 103, for example, and the CPU 101 executes the program code.
[0030] In the present example it is assumed that a user intends to utilize computer 100 to develop and / or test a software application.
[0031] To this end, the user executes the software development environment 104 on the CPU 101 .
[0032] The software development environment 104 enables users to develop and test applications 105 for various devices 106, i.e., for target hardware (such as embedded systems for controlling robotic devices including robot arms and autonomous vehicles) or for mobile (communication) devices. To this end, the CPU 101 can execute an emulator as part of the software development environment 104 to simulate the behavior of the corresponding device 106 for which the application is to be or has been developed. If the software development environment 104 is only used to test software from other sources, the software development environment 104 can also be regarded as or designed as a software testing environment.
[0033] The user can distribute the finished application to the corresponding device 106 via the communication network 107. Instead of via the communication network 107, this can also be done in other ways, for example by means of a USB stick.
[0034] Before this occurs, however, the user should test the application 105 to avoid distributing an application to the device 106 that does not function as specified.
[0035] One testing method is so-called fuzz testing. Fuzz testing (Fuzzing or Fuzz-Testing) is an automated software testing method in which invalid, unexpected or random data is fed as input to the computer program to be tested. The program is then monitored for anomalies such as crashes, lack of failed built-in code assertions or potential memory leaks.
[0036] Typically, fuzzers (i.e., test programs using fuzz testing) are used to test programs that process structured inputs. The structure is specified, for example, in a file format or file format or protocol and distinguishes between valid and invalid inputs. An effective fuzzer produces semi-valid inputs that are "valid enough" to not be directly rejected by the input parser of the program under test, but "invalid enough" to reveal unexpected behavior and edge cases that are not properly handled in the program under test.
[0037] The following describes the terminology used in conjunction with fuzz testing:
[0038] Fuzz testing (Fuzzing or Fuzz-Testing) is an automated testing process that sends randomly generated inputs to a target program (the program under test) and observes its responses.
[0039] A fuzzer or fuzz testing engine is a program that automatically generates input. Therefore, the fuzzer or fuzz testing engine is not associated with the software under test and does not perform instrumentation. However, the fuzzer or fuzz testing engine has the ability to instrument code, generate test cases and execute the program under test. Known examples are afl and libfuzzer.
[0040] A fuzz target is a software program or function that should be tested by fuzz testing. The main feature of a fuzz target should be that it takes potentially untrusted inputs generated by the fuzzer during the fuzz testing process.
[0041] A fuzz test is a combined version of a fuzzer and a fuzz target. Thus, a fuzz target can be instrumented code, where the fuzzer is associated with its input (i.e., provides the input). Fuzz tests are executable. A fuzzer can also start, observe, and stop multiple fuzz tests (typically hundreds or thousands per second), each with slightly different inputs generated by the fuzzer.
[0042] A test case is a specific input and a specific test run from a fuzz test. Usually, the runs that are of interest for reproducibility (finding new code paths or crashes) are stored. In this way, a specific test case with the corresponding input can also be executed on a fuzz target that is not connected to the fuzzer, such as a released version of the program.
[0043] Coverage-guided fuzzing uses code coverage information as feedback during fuzz testing to identify whether an input causes the execution of new code paths or blocks.
[0044] Generator-based fuzz testing (English: generation-based fuzzing) uses prior knowledge about the target program (fuzz target) to create test inputs. An example of such prior knowledge is the grammar corresponding to the input specification of the fuzz target, i.e. the input grammar of the fuzz target (i.e. the program to be tested).
[0045] Static instrumentation is the insertion of commands into a program (to be tested) to obtain feedback about the execution. The static instrumentation is mostly implemented by the compiler and can, for example, describe the code blocks reached during execution.
[0046] Dynamic instrumentation is controlling the execution of a program (to be tested) during runtime to generate feedback from the execution. The dynamic instrumentation is mostly implemented by operating system functionality or by using an emulator.
[0047] A debugger is a device or a program that can control a target device or a target program and can provide functions such as for calling register values or memory values and for pausing and executing a target program in individual steps.
[0048] ·Breakpoints are set by the debugger on commands of the target program or device so that execution stops when they are reached and the controlling process is notified of this.
[0049] Setting a (data) watchpoint by the debugger at a memory address of the target program or target device, so that execution is halted when the memory address is accessed, and the controlling process is informed of this by triggering an interrupt.
[0050] Embedded systems usually have a microcontroller that processes inputs and responds with outputs to perform specific tasks. Although microcontrollers use the same memory model as conventional user programs and are programmed using the same programming language, microcontroller programs are significantly more difficult to test. In order to enable debugging, microcontrollers usually provide the following possibilities: interrupting the program using breakpoints (stop points), traversing the commands of the program in individual steps, and setting watchpoints on storage addresses. When accessing the corresponding storage area, the watchpoint triggers an interrupt. Hardware breakpoints and watchpoints are typically implemented as physical registers in the debugging unit of the microcontroller, and therefore their number is limited and depends on the corresponding system. For example, for a typical microcontroller, the maximum number is four breakpoints and two data watchpoints. Usually watchpoints can be distinguished between read access and write access.
[0051] In particular, breakpoints and watchpoints can be used to implement debugger-controlled fuzz testing, eliminating the need for instrumentation.
[0052] Fuzz testing (and debugger-controlled fuzz testing) is very effective at finding bugs that trigger observable behavior, such as crashes or reboots. However, not all classes of bugs can be observed because the program silently fails on them. An example is the Heartbleed vulnerability. The core of the Heartbleed vulnerability is that Heartbleed only reads out of bounds of an array, while writes result in segmentation faults that are easily observable.
[0053] The Heartbleed vulnerability was only found with the help of Address Sanitizer (ASan). ASan inserts additional commands, metadata, and checks during the compilation of a program to prevent errors when memory is corrupted. When such Sanitizer commands are available in a program, more errors can be found when debugging the program than without the Sanitizer. Automated testing (such as fuzz testing) is particularly interesting when a Sanitizer is set up in the program to be tested (i.e. in the fuzz target) to find additional errors.
[0054] For embedded systems (such as data processing devices with ARM architecture), such sanitizers are not as easy to use as for standard platforms (such as x86 platforms). There are many reasons for this:
[0055] Embedded systems are too resource-constrained to implement a Sanitizer. For example, Asan requires double the memory, MSan (MemorySanitizer) requires 2.5 times the resources, and UBSan (UndefinedBehaviorSanitizer) even requires three times the working memory of the program.
[0056] The Sanitizer increases the size of the compiled binary. In the automotive industry, the size of such binaries often almost corresponds to the available flash memory of the target hardware. Therefore, the additional instrumentation of the Sanitizer does not fit in the flash memory.
[0057] The use of Sanitizers results in slower runtime of binaries on the corresponding hardware due to the Sanitizer's additional instrumentation and metadata collection and tracking. Embedded systems strongly depend on asynchronous events, such as interrupts, and thus Sanitizers may cause timing-based false positive errors, i.e., Sanitizers may introduce new errors during runtime.
[0058] Embedded systems usually do not have a user interface for displaying runtime errors. On x86 systems, for example, segmentation faults are forwarded to STDERR so that the user sees the crash. Instead, embedded systems fail silently, i.e. without the user noticing this, and restart after such a crash.
[0059] Therefore, according to various embodiments, a method is provided that enables memory monitoring (i.e., Sanitizer functionality) to be used for embedded systems, in particular, memory monitoring can be used for debugger-controlled fuzz testing. Here, the memory monitoring itself can be implemented with the help of a debugger (or a debugger for fuzz testing).
[0060] In debugger-based fuzz testing, the interaction between the system executing the test (and corresponding to, for example, the computer 100) and the target system (target hardware, such as an embedded system, such as the target device 106) is carried out via a debug connection (i.e., a debug interface), which is provided, for example, by a dedicated debugger hardware device. The test input data is transmitted to the target system 106 in the form of an input vector, for example, via WiFi or a CAN bus (depending on the type of the target device 106), that is, the communication network 107 is such a debug connection during this test (then when distributing the tested software, the communication network can be any other communication network). The system executing the test (hereinafter also referred to as the test system 100) controls the execution of the target program (i.e., the program to be tested) in the target system via the debug connection, that is, starts the execution and resumes the execution after an interrupt (especially an interrupt triggered by a data monitoring point).
[0061] The debugger-controlled Sanitizer does not require plugging or emulation, but only requires a debug interface with the target system (e.g., an embedded system on which the software is executed) with the possibility of setting breakpoints and monitoring points. This type of debug interface and debugging capabilities are universal and also available, which leads to the wide and simple applicability of the method described below. In addition, since most or all of the information related to the Sanitizer is collected and stored on the host side of the debugger (i.e., in the test system 100), the embedded system can also be tested with its completed version (e.g., the sold version), so the memory of the target system is only slightly loaded, for example, for metadata. The size of the compiled binary file of the target program does not increase, because the binary file is used during testing as if it were set for the target system 106.
[0062] When a breakpoint is reached, the debugger halts the target system. Therefore, the approach described below leads to time-based false alarms only in rare cases. These false alarms can also be eliminated by other testing techniques, such as by subsequently verifying the errors found on the target system. Using a debugger also provides a good view of the internal affairs of the target system.
[0063] Memory is typically addressed byte by byte, regardless of the bus width of the executing processor. However, memory accesses by a program typically must be directed according to the data width of the corresponding memory access instruction (i.e., the size of the data element accessed by the memory access instruction). For example, a 32-bit (4-byte) load operation requires that the storage address to which the 32-bit (4-byte) load operation is applied (i.e., obtained as an argument) is divisible by 4 (bytes).
[0064] The approach described below is used to detect undefined behavior, in particular behavior caused by executing instructions with undirected pointers. According to various embodiments, undirected memory accesses (i.e., memory accesses to undirected addresses, such as 32-bit accesses to memory addresses that cannot be divided by 4 in the example above) are thus detected.
[0065] Memory accesses with undirected addresses (e.g., undirected pointers obtained as arguments by such memory access instructions) can be dangerous because they typically comply with the corresponding programming language standard but may cause unexpected behavior or, depending on the architecture, may at least result in performance degradation. Therefore, memory accesses with undirected addresses can be considered program errors.
[0066] Examples of x86 assembler code for storing a constant value of 2 at the address stored in EBX for different data widths are as follows:
[0067] mov BYTE PTR[ebx],2; the address in register EBX does not need to be directed
[0068] mov WORD PTR[ebx],2; the address in register EBX must be oriented to 2 bytes
[0069] mov DWORD PTR[ebx],2; the address in register EBX must be 4 bytes long
[0070] mov QWORD PTR[ebx],2; the address in register EBX must be 8-byte oriented
[0071] It should be noted here that the address to which a memory access is performed is typically unknown at compile time: in the example above, the address is located in register EBX and is therefore known only at runtime. Therefore, according to various embodiments, runtime Sanitizer functionality is provided (with the aid of a debugger that does not need to be run on the execution system). In particular, according to various embodiments, when a memory access instruction (e.g. a memory access assembler instruction, such as the above-mentioned MOV instruction) is called in the computer program to be tested, it is checked with the aid of the connected debugger whether the address to which the memory access instruction is applied (i.e. the address of one of the arguments of the memory access instruction) is correctly directed. As described above, it is assumed here that the test system 106 is connected to the execution system (e.g. an embedded system) 106 with the aid of a debug connection, and the execution of the computer program to be tested on the execution system is tested with the aid of a debugger.
[0072] For example, the test system 100 performs the following:
[0073] 1. Set breakpoints on (memory access) instructions (e.g., assembler instructions) that read from or write to the memory (of the execution system). In order to select the memory access instructions to which the breakpoints are set, various strategies can be used (e.g., randomly or according to a list processed in multiple fuzz testing iterations, i.e., so that each memory access instruction function has been equipped with a breakpoint, e.g., in at least one fuzz testing iteration, in order to test all memory access instructions, if there are not enough breakpoints available for all memory access instructions, the same test case can be executed for different placements of breakpoints.).
[0074] 2. When executing the computer program, if one of the set breakpoints is triggered, that is, the memory access instruction is called, the test system 100 performs one of the following according to the execution system (that is, the system architecture of the execution system) and the memory access instruction:
[0075] a. Evaluate the opcode and optionally the parameters (i.e., arguments) to determine the data width (typically 1, 2, 4, or 8 bytes) and the memory access instruction and the memory address to which the memory access instruction applies (e.g., in the case of an assembler instruction);
[0076] b. deriving the data width of the memory access instruction and the memory address to which the memory access instruction is applied from the runtime information obtained from the debugger;
[0077] c. deriving the data width of the memory access instruction and the storage address to which the memory access instruction is applied by static analysis (reverse engineering) of the binary file of the computer program;
[0078] d. If the memory access instruction has a standard data width (e.g., 32 bits), the data width of the memory access instruction is determined from information about the architecture of the execution system, and the storage address to which the memory access instruction is applied is determined by one of the other methods a to c.
[0079] 3. If the determined storage address is not oriented according to the data width of the memory access instruction (i.e., for example, although the data width is 4 bytes, it cannot be divided by 4), an access with an unoriented storage address is found. In response to this, it is indicated that the computer program has an error, for example, a warning is displayed or logged, execution is interrupted, an exception is triggered, or the computer program crashes (so that, for example, the test program is identified as having an error during fuzz testing).
[0080] In summary, according to different embodiments, the following are provided: Figure 2 The method shown in .
[0081] Figure 2 A flow chart 200 is shown which represents a method for testing a computer program according to one specific embodiment.
[0082] In 201 , one or more breakpoints are set on one or more memory access instructions in a computer program.
[0083] In 202 , a computer program is executed, wherein when one of the set breakpoints is triggered, in 203 it is determined whether the memory access instruction is used to access a data element having a size required for orientation to a memory address to which the data element is written or from which the data element is read, and if necessary the required orientation.
[0084] At 203, if the memory access instruction is for accessing a data element having a size required for orientation to a memory address to which the data element is written or from which the data element is read, it is determined whether the memory address accessed by the memory access instruction satisfies the required orientation.
[0085] At 204 , in response to determining that the memory address accessed by the memory access instruction does not satisfy the required orientation, a display is triggered (ie, “initiated”) that the computer program has an error.
[0086] Figure 2 The method can be performed by one or more computers having one or more data processing units. The term "data processing unit" can be understood as any type of entity that enables processing of data or signals. For example, data or signals can be processed according to at least one (i.e., one or more) specific functions performed by the data processing unit. The data processing unit may include an analog circuit, a digital circuit, a logic circuit, a microprocessor, a microcontroller, a central unit (CPU), a graphics processing unit (GPU), a digital signal processor (DSP), a programmable gate array integrated circuit (FPGA), or any combination thereof, or may be composed of an analog circuit, a digital circuit, a logic circuit, a microprocessor, a microcontroller, a central unit (CPU), a graphics processing unit (GPU), a digital signal processor (DSP), a programmable gate array integrated circuit (FPGA), or any combination thereof. Any other means for implementing the corresponding functions described in more detail herein may also be understood as a data processing unit or a logic circuit device. One or more of the method steps described in detail here may be performed (e.g., implemented) by a data processing unit through one or more specific functions performed by the data processing unit.
[0087] Figure 2 The control software can be used in a test program in a manner such as control software for a robotic device. The term "robotic device" may be understood to refer to any technical system, such as a computer-controlled machine, a vehicle, a household appliance, a power tool, a manufacturing machine, a personal assistant or an access control system. The control software can also be used for data processing systems, such as navigation equipment.
[0088] Figure 2 The method is for example performed by a test device (e.g. Figure 1 computer 100 and target device 106) to execute.
[0089] Although specific embodiments have been shown and described herein, it is recognized by those skilled in the art that the specific embodiments shown and described may be replaced by various alternatives and / or equivalent implementations without departing from the scope of protection of the present invention. The present application should encompass any adaptation or variation of the specific embodiments discussed herein. Therefore, the present invention is intended to be limited only by the claims and their equivalents.
Claims
1. A method for testing a computer program (105), the method comprising: setting one or more breakpoints at one or more memory access instructions in a computer program (105); Executing the computer program (105); upon triggering one of the set breakpoints, determining whether a memory access instruction is used to access a data element having a size required for orientation relative to a memory address to which the data element is written or from which the data element is read, and determining the required orientation if necessary; if the memory access instruction is for accessing a data element having a size required for orientation at a memory address to which the data element is written or from which the data element is read, determining whether the memory address accessed by the memory access instruction satisfies the required orientation; as well as In response to determining that the memory address accessed by the memory access instruction does not satisfy the required orientation, a display is triggered that the computer program (105) has an error.
2. The method according to claim 1, comprising: In response to determining that the memory address accessed by the memory access instruction does not satisfy the required orientation, the display that the computer program (105) has an error is triggered by triggering an abort of the computer program (105).
3. The method according to claim 1 or 2, comprising: Determining whether the memory access instruction is for accessing a data element having a size required for orientation relative to a storage address to which the data element is to be written or from which the data element is to be read, and determining the required orientation if necessary, is performed by evaluating an opcode of the memory access instruction, evaluating execution information by a debugger, results of a static analysis of the computer program (105), information about the architecture of a system on which the computer program (105) is executed.
4. The method according to any one of claims 1 to 3, comprising: Multiple test passes are executed and breakpoints are set on different memory access instructions for different test passes.
5. The method according to any one of claims 1 to 4, comprising: The computer program (105) is executed on the embedded system (106) and the following steps are performed by a test system (100) connected to the embedded system (106): setting a breakpoint, determining whether the memory access instruction requires orientation, determining the required orientation if necessary, determining whether the memory access instruction satisfies the orientation if necessary, and triggering a display if necessary: the computer program (105) has an error.
6. The method according to any one of claims 1 to 5, wherein the computer program (105) is a control program for a robotic device, and the computer program (105) is used to control the robotic device based on the results of the test of the computer program (105). 7 . A testing device, which is configured to carry out the method according to claim 1 .
8. A computer program having instructions which, when executed by a processor, cause the processor to perform the method according to any one of claims 1 to 6.
9. A computer-readable medium storing instructions, which, when executed by a processor, cause the processor to perform the method according to any one of claims 1 to 6.
