(guss) tbreak 9000 Time breakpoint installed at 9,000 (+9000) simulated insns. (guss) run Topsy 1.1 (c) 1996-1998, ETH Zurich, TIK ($Id: Configuratio Time breakpoint 1 caught at <0x8002647c> (guss) show register sp sp 0x80000f7cIn the example above a time breakpoint is inserted at 9000 simulated instructions. The simulation session is started and after 9000 instructions the simulator halts execution.
As in GDB, it is possible to list information about installed breakpoints. This is done (as in GDB) with the info breakpoints command.
(guss) info breakpoints Num Type Hits Physical Virtual What 1 time breakpoint 1 9,000 ticks 2 breakpoint 0 0x00010242 0x80010242Since breakpoint 1 is a time breakpoint no physical or virtual address is listed. Breakpoint 2 is a "normal" breakpoint in that sense that is breaks the execution flow whenever an instruction at 0x00010242 is executed. Note that breakpoints is set on physical addresses.
Another example, this time made with the OpenRISC target of GUSS. This example runs the ORPMON, a monitor software for the OpenRISC architecture. A breakpoint on function _printf is installed. Since the OpenRISC target is not configured with a MMU and has no memory aliases it possible to omit the virtual flag to the break command.
Simulation is started and breakpoint 1 breaks at _printf, as it should. Since GUSS does not have back-tracing facilities as GDB does, it is not possible to get a stack trace to know where the call was made from. Instead the branch-profile command is used to display branches made into the _printf function. More on that command in the next section.
(guss) break _printf (guss) info breakpoints Num Type Hits Physical Virtual What 1 breakpoint 0 0x000031f0 0x000031f0 <_printf> (guss) run Breakpoint 1 caught at 31f0 <_printf> (guss) branch-profile _printf Branches into physical range: 0x31f0-0x3d74 Source Target physical virtual (source) physical virtual (source) count 0x00002ef0 0x00002ef0 cpu#0 0x000031f0 0x000031f0 cpu#0 1 ...
(guss) wwatch 0x30000000 +16 (guss) info breakpoints Num Type Hits Physical Virtual What 1 memory watchpoint 0 0x30000000 0x30000000 (0x10 bytes) (guss) run Memory watchpoint 1 caught at 4027c0In the example above a write watchpoint is installed for the memory range 0x30000000 to 0x30000015. The watchpoint is hit at 0x4027c0 (0x414 in chunk_alloc.) To install a read watchpoint, use the rwatch command, or the awatch to install a access watchpoint (either read or write).
Accessing address 0x30000004
Since all branches is stored in a hash table it is possible to perform difference analysis on the call-graph. GUSS can for example display all branches from, within and to a specified range. Example:
(guss) branch-profile/v begin Branches into physical range: 0x1fc00200-0x1fc0030c Source Target physical virtual (source) physical virtual (source) count 0x1fc00000 0xbfc00000 cpu#0 0x1fc00200 0xbfc00200 cpu#0 1 0x1fc0039c 0xbfc0039c cpu#0 0x1fc00308 0xbfc00308 cpu#0 1 Branches from physical range: 0x1fc00200-0x1fc0030c Source Target physical virtual (source) physical virtual (source) count 0x1fc00300 0xbfc00300 cpu#0 0x1fc0030c 0xbfc0030c cpu#0 1 Branches within physical range: 0x1fc00200-0x1fc0030c Source Target physical virtual (source) physical virtual (source) count 0x1fc002f8 0xbfc002f8 cpu#0 0x1fc002e8 0xbfc002e8 cpu#0 418 0x1fc002b0 0xbfc002b0 cpu#0 0x1fc00294 0xbfc00294 cpu#0 63The example above displays all branches from, within and to the function begin. GUSS collects statistics on physical addresses, but the symbol table contains virtual addresses, so the v flag must be used with the branch-profile command.
The command also translate the physical addresses into virtual addresses, if so is possible. Under the column source is the processor that did the translation listed. If no processor could do a translation for the physical address *unknown* is printed.
It is also possible to display symbol table information with the command. This is done by setting the print-arc-symbols variable to on.
(guss) set print-arc-symbols on (guss) branch-profile/v begin Branches into physical range: 0x1fc00200-0x1fc0030c Source Target physical virtual (source) physical virtual (source) count 0x1fc00000 0xbfc00000 cpu#0 0x1fc00200 0xbfc00200 cpu#0 1 Branch from <__start> to <begin> 0x1fc0039c 0xbfc0039c cpu#0 0x1fc00308 0xbfc00308 cpu#0 1 Branch from <entry+0x90> to <begin+0x108> Branches from physical range: 0x1fc00200-0x1fc0030c Source Target physical virtual (source) physical virtual (source) count 0x1fc00300 0xbfc00300 cpu#0 0x1fc0030c 0xbfc0030c cpu#0 1 Branch from <begin+0x100> to <entry> ...You can see that the function begin was called from __start, and on address 0xbfc0030 (begin+0x100) it calls the function entry which returns to begin+0x108 from the address 0xbfc0039c.
Example, say that you want to know where the hot spots of the simulated program is. Say also that you want to focus on branches.
(guss) set branches-from-weight 1 (guss) set branches-to-weight 1 (guss) weight Summary for physical memory: physical virtual (source) decode pc from to weight 0x00400000 0x00400000 cpu#0 824 65,130,898 3,684,368 3,684,371 7,368,739 0x00407000 0x00407000 cpu#0 339 931 88 90 178 0x00402000 0x00402000 cpu#0 544 919 61 58 119 0x00411000 0x00411000 cpu#0 475 793 54 58 112 0x0042e000 0x0042e000 cpu#0 164 621 51 51 102 0x0041a000 0x0041a000 cpu#0 271 509 40 42 82 0x0042a000 0x0042a000 cpu#0 311 297 37 36 73 0x0042d000 0x0042d000 cpu#0 196 268 34 34 68 0x0042c000 0x0042c000 cpu#0 237 310 34 33 67 0x0042b000 0x0042b000 cpu#0 211 320 27 26 53 Number of insns executed (based on branch arcs): 65,137,785The weight command calculates an linear sum of the entire memory, sorting and displaying the largest values. Now you find that most of the action is in the page with the physical address 0x400000.
Say you want to see more in detail. For this the summary command can be used. It takes a memory range or a symbol name as argument. It splits the memory range into buckets of 64 bytes and does a linear sum for each of those and displays the larges values.
(guss) summary 0x00400000 0x00401000 Summary for range: 0x400000-0x401000 (in buckets of 64 bytes) physical virtual (source) decode pc from to weight 0x00400580 0x00400580 cpu#0 16 9,837,932 2,088,903 125,104 2,214,007 0x00400500 0x00400500 cpu#0 16 15,230,983 4,801 2,002,500 2,007,301 0x00400540 0x00400540 cpu#0 16 31,015,775 961,203 927,004 1,888,207 0x00400700 0x00400700 cpu#0 16 1,928,444 240,867 240,571 481,438 0x00400480 0x00400480 cpu#0 16 3,261,000 114,000 217,200 331,200 0x004004c0 0x004004c0 cpu#0 16 3,191,390 271,501 47,100 318,601 0x00400440 0x00400440 cpu#0 12 488,400 0 121,500 121,500 0x004006c0 0x004006c0 cpu#0 16 27,088 2,430 294 2,724 0x00400600 0x00400600 cpu#0 16 19,504 0 2,430 2,430 0x00400800 0x00400800 cpu#0 16 3,925 600 300 900If you want to go even deeper and see per-instruction statistics the disassemble command can be used. Example of such.
(guss) disassemble 0x00400580 0x004005a0 (physical) decode pc from to (disassembled insn) 0x00400580 1 2,002,802 0 39,003 sll a3,v1,0x1 0x00400584 1 2,002,802 0 0 slt t3,t2,a3 0x00400588 1 2,002,802 1,759,800 0 beqz t3,400524If you find it hard to remember what the different profilers mean (decode, pc, ...) you can always issue the info profilers command.
0x0040058c 1 2,002,802 0 0 sll t6,v1,0x2 0x00400590 1 243,002 0 0 lw a2,0(t4) 0x00400594 1 243,002 0 0 lw a3,0(a0) 0x00400598 1 243,002 0 0 addiu t2,t2,-1 0x0040059c 1 243,002 0 0 sw a2,0(a0)
(guss) info profilers Active profilers, listed left to right. Column 0: Instruction has been decoded (1/0) (decode-flag-weight = 0) Column 1: Count of instruction execution (based on branch arcs) (pc-weight = 0) Column 2: Number of (taken) branches from address (branches-from-weight = 1) Column 3: Number of (taken) branches to address (branches-to-weight = 1)
One important aspect of running a program in a simulator is that at any time be able to inspect the state of the system. For example, the user would like to know how much memory the program consumes, and what regions of the memory has been used for data and instruction accesses.
The command show pmap does exactly that. It lists all configured memory regions and display their usage. In the example below D means data page and I means that instructions has been fetched from the page.
(guss) show pmap Memory map for global physical memory: 0x00000000: I...............................IIIIIIIIDDDDDDDD.............DDD 0x00040000: .DDDDDDD........................................................ 0x000c0000: DDIIIDDD.......................................................D Pages of 4K allocated: 36 (147,456 bytes of host memory)Regions with zero accesses is omitted. The command also displays the number of 4K pages Thais has been allocated by the simulator. This gives an estimation of how much memory the simulator uses.
It is of course possible to display values of processor registers. This is done with the show register command. Example;
(guss) show register cc a1 pc 0x800255e4 a1 0x8003ec7cNote that the program counter holds a virtual address. The example is made with the MIPS target of GUSS, and region 0x80000000 happen to be an alias for region 0x00000000. This means that the processor is actually executing instructions at physical address 0x000255e4.