1b8021494Sopenharmony_ciDebugging with the VIXL Simulator
2b8021494Sopenharmony_ci=================================
3b8021494Sopenharmony_ci
4b8021494Sopenharmony_ciThe VIXL AArch64 simulator contains a basic debugger which can be used to debug
5b8021494Sopenharmony_cisimulated applications. The debugger supports basic debugging features such as
6b8021494Sopenharmony_cisetting breakpoints, stepping through simulated instructions and printing
7b8021494Sopenharmony_cisimulator specific information, for example: printing the values of a register
8b8021494Sopenharmony_cior printing instructions at specified addresses.
9b8021494Sopenharmony_ci
10b8021494Sopenharmony_ciUsing the Debugger
11b8021494Sopenharmony_ci------------------
12b8021494Sopenharmony_ci
13b8021494Sopenharmony_ciIn order to use the debugger it first needs to be enabled in the simulator.
14b8021494Sopenharmony_ci
15b8021494Sopenharmony_ci```C++
16b8021494Sopenharmony_ci    Decoder decoder;
17b8021494Sopenharmony_ci    Simulator simulator(&decoder);
18b8021494Sopenharmony_ci    simulator.SetDebuggerEnabled(true);
19b8021494Sopenharmony_ci```
20b8021494Sopenharmony_ci
21b8021494Sopenharmony_ciOnce enabled, the debugger will be activated whenever a breakpoint (brk) is
22b8021494Sopenharmony_ciencountered by the simulator. For example:
23b8021494Sopenharmony_ci
24b8021494Sopenharmony_ci```asm
25b8021494Sopenharmony_ci    add x1, x0, #5
26b8021494Sopenharmony_ci    mov x2, #2
27b8021494Sopenharmony_ci
28b8021494Sopenharmony_ci    brk 0   // Debugger activated here.
29b8021494Sopenharmony_ci
30b8021494Sopenharmony_ci    sub x3, x1, x2
31b8021494Sopenharmony_ci```
32b8021494Sopenharmony_ci
33b8021494Sopenharmony_ciFurther breakpoints can be set either programmatically or interactively in the
34b8021494Sopenharmony_cidebugger itself. For example, to set breakpoints programmatically:
35b8021494Sopenharmony_ci
36b8021494Sopenharmony_ci```C++
37b8021494Sopenharmony_ci    // 'func' is an AARCH64 assembly function.
38b8021494Sopenharmony_ci    extern "C" void func();
39b8021494Sopenharmony_ci
40b8021494Sopenharmony_ci    Debugger* debugger = simulator.GetDebugger();
41b8021494Sopenharmony_ci
42b8021494Sopenharmony_ci    // Register a breakpoint at a fixed (absolute) address.
43b8021494Sopenharmony_ci    debugger->RegisterBreakpoint(0x00007ffbc6d38000);
44b8021494Sopenharmony_ci
45b8021494Sopenharmony_ci    // Register a breakpoint to an already existing assembly function.
46b8021494Sopenharmony_ci    debugger->RegisterBreakpoint(reinterpret_cast<uint64_t>(&func));
47b8021494Sopenharmony_ci```
48b8021494Sopenharmony_ci
49b8021494Sopenharmony_ciOr to set breakpoints interactively once the debugger has been activated:
50b8021494Sopenharmony_ci
51b8021494Sopenharmony_ci```sh
52b8021494Sopenharmony_ci    sim> break 0x00007ffbc6d38000
53b8021494Sopenharmony_ci```
54b8021494Sopenharmony_ci
55b8021494Sopenharmony_ciThe debugger has a variety of useful commands to control program flow (e.g:
56b8021494Sopenharmony_cistep, next, continue) and inspect features of the running simulator (e.g:
57b8021494Sopenharmony_ciprint, trace). To view a list of all supported commands
58b8021494Sopenharmony_ciuse "help" at the debugger prompt.
59b8021494Sopenharmony_ci
60b8021494Sopenharmony_ci```sh
61b8021494Sopenharmony_ci    sim> help
62b8021494Sopenharmony_ci```
63b8021494Sopenharmony_ci
64b8021494Sopenharmony_ciExtending the Debugger
65b8021494Sopenharmony_ci----------------------
66b8021494Sopenharmony_ci
67b8021494Sopenharmony_ciThe debugger can be extended with custom commands to allow for greater
68b8021494Sopenharmony_ciflexibility in debugging individual applications. This could be used for a
69b8021494Sopenharmony_civariety of applications, for example printing out object specific information
70b8021494Sopenharmony_cifrom an address.
71b8021494Sopenharmony_ci
72b8021494Sopenharmony_ciTo create a custom debugger command, extend the DebuggerCmd class located in
73b8021494Sopenharmony_cidebugger-aarch64.h and implement its methods.
74b8021494Sopenharmony_ci
75b8021494Sopenharmony_ci```C++
76b8021494Sopenharmony_ci    class PrintObjectCmd : public DebuggerCmd {
77b8021494Sopenharmony_ci     public:
78b8021494Sopenharmony_ci      PrintObjectCmd(Simulator* sim)
79b8021494Sopenharmony_ci            : DebuggerCmd(sim,
80b8021494Sopenharmony_ci                          "printobject",
81b8021494Sopenharmony_ci                          "po",
82b8021494Sopenharmony_ci                          "<address>",
83b8021494Sopenharmony_ci                          "Print a custom object located at the given address.")
84b8021494Sopenharmony_ci      {}
85b8021494Sopenharmony_ci
86b8021494Sopenharmony_ci      // Called when the command word is given to the interactive debugger.
87b8021494Sopenharmony_ci      DebugReturn Action(const std::vector<std::string>& args) override {
88b8021494Sopenharmony_ci        // We want exactly 1 argument (an address) given to the printobject
89b8021494Sopenharmony_ci        // command.
90b8021494Sopenharmony_ci        if (args.size() != 1) {
91b8021494Sopenharmony_ci            fprintf(ostream_, "Error: incorrect command format.");
92b8021494Sopenharmony_ci            return DebugContinue;
93b8021494Sopenharmony_ci        }
94b8021494Sopenharmony_ci
95b8021494Sopenharmony_ci        auto addr = Debugger::ParseUint64String(args.front());
96b8021494Sopenharmony_ci        if (addr) {
97b8021494Sopenharmony_ci            fprintf(ostream_, "Error: could not get address from string.");
98b8021494Sopenharmony_ci            return DebugContinue;
99b8021494Sopenharmony_ci        }
100b8021494Sopenharmony_ci
101b8021494Sopenharmony_ci        // Convert the address given to a custom object and then print it.
102b8021494Sopenharmony_ci        CustomObject object = reinterpret_cast<CustomObject>(*addr);
103b8021494Sopenharmony_ci        object.print();
104b8021494Sopenharmony_ci      }
105b8021494Sopenharmony_ci    };
106b8021494Sopenharmony_ci```
107b8021494Sopenharmony_ci
108b8021494Sopenharmony_ciThen simply register the new command with the debugger.
109b8021494Sopenharmony_ci
110b8021494Sopenharmony_ci```C++
111b8021494Sopenharmony_ci    Debugger* debugger = simulator.GetDebugger();
112b8021494Sopenharmony_ci
113b8021494Sopenharmony_ci    debugger->RegisterCmd<PrintObjectCmd>();
114b8021494Sopenharmony_ci```
115