Carnegie Mellon
SCS logo
Computer Science Department
home
syllabus
staff
schedule
lecture
projects
homeworks
 
 

15-410 Simics Command Guide


What's Simics?

Simics is a system simulation platform originally developed by Virtutech, a spin-off of the Swedish Institute of Computer Science (SICS), which was later acquired by Wind River. Simics is an extensible simulation/debugging platform which can support the execution of networks of simulated machines running off-the-shelf operating systems. Wind River graciously supports our educational mission by providing CMU with a site license free of charge. Before using Simics for any non-coursework purposes, please contact your instructor to make sure your proposed use does not conflict with our Simics license.

15-410 Basic Simics Commands

Here is a brief listing of useful Simics commands. A more detailed reference is the Simics User Guide, available in the 410 simics/doc directory. To get more help on any of these commands within Simics, type help COMMANDNAME. Simics supports tab-key command completion and command history.

Below, anything in [] is an optional argument, while anything in () means you must choose one and only one option.

Running Simics

r
Starts the simulation. Once a simulation has been started, it may not be restarted. To give up on a simulation and start anew, quit the simulation and restart Simics.

c
Continues the simulation after a breakpoint or error has occurred. Note that you may not be able to continue reliably after some types of errors.

q
Exits Simics.

ctrl-c (control + c)
Interrupts the currently running simulation so that commands may be entered (debugging commands, quit, etc).

stepi [NUM]
Steps through the next NUM instructions. NUM defaults to 1. If a breakpoint occurs while stepping, it still causes a break in execution.

n
Step to next source line and stop. Note that there are multiple possible meanings of this; if you find the results of this command surprising, think carefully about how its semantics might differ from your expectation and why. This command is a local Python-based debugger extension written by 410 TA Michael Berman.

Accessing Registers

pregs
Prints the contents of all the general purpose registers (eax, ecx, edx, ebx, esi, edi, ebp, esp), the value of the program counter (eip), the contents of EFLAGS, and various other registers.

%REGNAME
Prints the contents of register REGNAME. For example, %eax prints the contents of the eax register. This output will be in decimal. To print it in hex, try print -x %REGNAME (see below for more information on the print command).

read-reg REGNAME
Same as %REGNAME.

write-reg REGNAME NEWVALUE
Sets the value stored in register REGNAME to NEWVALUE. For example, write-reg eax 0 would put 0 into register eax.

Accessing Memory

x l:ADDRESS [SIZE] or x p:ADDRESS [SIZE]
Prints the contents of memory starting at ADDRESS and continuing for SIZE bytes. First lists the starting address, then the bytes in memory, and last an attempt to translate the bytes into ASCII (the ASCII will be nonsensical unless actual words are stored in the location). l indicates the ADDRESS is a virtual/logical memory address, while p indicates the ADDRESS is a physical memory address. If SIZE is not given, the default is 16 bytes. Remember, you are dealing with a little endian machine.

logical-to-physical ADDRESS
Displays the physical address that the logical/virtual address ADDRESS maps to. The output is in decimal, but you can combine it with print to get hex output. The command may be abbreviated as l2p. See also cpu0_tlb.info/cpu0_tlb.status, cpu0.tablewalk.

get ADDRESS [SIZE]
Gets SIZE bytes starting from physical address ADDRESS. SIZE defaults to 4 and can be no larger than 8.

set ADDRESS VALUE [SIZE]
Sets SIZE bytes starting from physical address to VALUE. SIZE defaults to 4 and can be no larger than 8.

stack-trace [MAXDEPTH]
Displays a stack trace up to at most MAXDEPTH (default is 64). The bt and where commands are synonyms for stack-trace. You can use up and down to move around in the stack.

list [-s] FUNCTION [LINES]
Displays up to LINES lines of code of the indicated FUNCTION (you may specify the starting point in other ways, such as file & line; see the documentation). If you specify -s the listing will interleave assembly code with your C source code.

whereis ADDRESS
Attempts to display an address in symbolic form, i.e., to find a symbol associated with the address. In some situations Simics may give you a nonsense answer. For example, if a thread from Program A is running and you inquire about an address in Program B, you will get a nonsensical answer. You can try forcing the use of a particular symbol table via xxx_prog.whereis(ADDRESS) to use the symbol table of a program called xxx.

"Hidden" (non-register) CPU state

cpu0_tlb.status and cpu0_tlb.info
Print some information about the contents of the translation lookaside buffer (not needed for Projects Zero through Two). There are additional cpu0_tlb commands as well. Also possibly useful: cpu0.tablewalk).

cpu0.print-idt, cpu0.print-gdt, and cpu0.print-tss
Briefly summarizes the contents of the IDT/GDT/TSS.

pic0.status
Briefly summarizes the status of the legacy i8259 Programmable Interrupt Controller (PIC). You can get more information via alias pic0 and trace-io system.motherboard.southbridge.pic.

pit0.status
Briefly summarizes the status of the legacy i8253 Programmable Interval Timer (PIT). You can get more information via alias pit0 and may find the trace-io command useful.

ps2.status
Briefly summarizes the status of the legacy i8042 PS/2 keyboard/mouse interface. You can get more information via alias ps2 and may find the trace-io command useful.

vga0.status
Summarizes the status of VGA graphics adaptor. You can get more information via alias vga0 and may find the trace-io command useful.

What Time Is It?

cpu0.print-time
Prints the number of executed instructions and, more usefully for this class, the amount of "wall clock time" which has elapsed inside the virtual world. This may be useful for verifying some of your driver code.

Breakpoints

break ADDRESS [LENGTH] [-r] [-w] [-x]
Sets a breakpoint of the specified modes for access in the LENGTH bytes starting at ADDRESS. Any combination of modes can be set, with r specifying memory read, w specifying memory write, and x specifying execute. Debugging some problems is much easier if you specify a physical address rather than a virtual address (see the x command above). Some addresses are particularly useful, such as 0x100000 and 0x1000000. The Simics breakpoint facility is fairly sophisticated, so you can do things like system.cell_context.tbreak 0x00100000 4096 or system.cell_context.tbreak 0x01000000 4096.

break-after-boot EXPRESSION [LENGTH] [-r] [-w] [-x]
Sets a deferred breakpoint on the address given by EXPRESSION; the EXPRESSION will be evaluated immediately after the kernel declares that it has booted. This command can be called any time before the kernel boots, including before the first instruction of the simulation has run. A particularly useful EXPRESSION might be kernel_main (which cannot be evaluated before the boot loader has finished).

display EXPRESSION
Specifies an expression which Simics will evaluate when it is about to print a prompt. This can save you from frequently re-typing a psym command.

list-breakpoints
Lists all breakpoints. Information includes whether the breakpoint is a virtual or physical address, the modes to break on (read, write, execute), whether it is enabled or disabled, the start and stop address, and the number of times the breakpoint has been reached.

enable (-all | ID)
Enables all breakpoints or just breakpoint with id ID.

disable (-all | ID)
Disables all breakpoints or just breakpoint with id ID.

delete (-all | ID)
Deletes all breakpoints or just breakpoint with id ID.

break-exception ("NAME" | NUMBER | -all | -list)
Asks Simics to stop when a particular exception is raised. Since the built-in documentation is very coy about the supported names and numbers for the x86 target, here is a table.
NumberName
0 Divide_Error_Exception
1 Debug_Exception
2 NMI_Interrupt
3 Breakpoint_Exception
4 Overflow_Exception
5 BOUND_Range_Exceeded_Exception
6 Invalid_Opcode_Exception
7 Device_Not_Available_Exception
8 Double_Fault_Exception
9 Coprocessor_Segment_Overrun
10 Invalid_TSS_Exception
11 Segment_Not_Present
12 Stack_Fault_Exception
13 General_Protection_Exception
14 Page_Fault_Exception
16 Floating_Point_Error_Exception
17 Alignment_Check_Exception
18 Machine_Check_Exception

Printing variables, the results of expressions, and print formatting

psym (VARNAME | "VARNAME" | FUNCTIONNAME)
Prints the value of variable VARNAME or function FUNCTIONNAME and possibly associated type information. You can perform more complex operations such as casting and dereferencing if you use the quote version. Note that the symbols must have been loaded for this command to work properly (we have taken care of this for you).

Observe that psym "&(thr_cb->exitstatus)" lets you determine the address of a particular item in a data structure. Also, if you are patient you can print an entire linked list from the debugger via a sequence of commands like
psym "*(head)"
psym "*(head->next)"
psym "*(head->next->next)"

sym (VARNAME | FUNCTIONNAME)
Similar to psym, except can be used in combination with other commands. For example, any command calling for an ADDRESS can use (sym FUNCTIONNAME) instead. If you had a function called test, you could do break -x (sym test) rather than having to determine the memory location of test.

print [(-x | -o | -b | -s)] VALUE [SIZE]
Allows for printing in different formats and can print any value that can be expressed as an integer. Arithmetic operations are allowed to create VALUE and the results of other commands can be used. Outputs types are -x for hex, -o for octal, -b for binary, and -s for signed integer.

HindSight Reverse Execution Support

Disclaimer!

This works only sometimes! It is not to be considered a replacement for other debugging techniques and thought. In particular, we have seen simulation state corruption, usually resulting in very strange kernel panics, but not always. If you see the world getting stranger and stranger, and are using HindSight, consider repeating your tests without reversing.

OK, OK, I get it...

HindSight is not enabled by default, and will subject your simulation to something like a 2x slowdown as well as eat gobs of memory at times, so you should enable it only for certain parts of your testing.

To enable HindSight, we must set a "bookmark" at the first time we are interested in, which we might name "first".

set-bookmark first

If any bookmarks are set, HindSight is running. Note that Simics can't back up earlier than the first bookmark.

At any point you can list bookmarks by saying

list-bookmarks

Bookmarks may be deleted via

delete-bookmark name

There are several reversing functions, corresponding to their forward-going symmetric partners.

rstepi count Steps backwards count instructions, or 1 if count is omitted.
rnext Steps backwards one source line, not entering subroutine calls ("unreturns" ?).
uncall Runs backwards until just before the current function was called. Note that this has been observed to frequently bail out early for somewhat mysterious reasons, so your mileage may vary.
reverse-to bookmark Jumps the simulation state backward to the bookmark named bookmark.
skip-to bookmark Jumps the simulation state forward to the bookmark named bookmark.

Special Reference-Kernel Support for Thread Debugging

Disclaimer!

This works only sometimes! It is not to be considered a replacement for other debugging techniques and thought. In particular, we have only lightly tested these codepaths. If it breaks for you, please tell us and we'll do our best.

tidinfo tid Dumps the user-mode state of thread tid

The output of tidinfo is approximately:

REGISTER DUMP FOLLOWS
 CS = 0x00000043, EFLAGS = 0x00010246, SS = 0x0000004b
 EIP = 0x0100004a, ESP = 0xffffffa0, EBP = 0xffffffcc
 EDI = 0x00000000, ESI = 0x00000000, EAX = 0x31337000
 EBX = 0x00000000, ECX = 0x00000000, EDX = 0x01000c0a

The output describes the state of the thread the last time it executed an instruction in user mode. Producing this output involves some cooperation between Simics and the reference kernel, so it is possible for you to observe side effects after using it. However, you can generally assume that the same thread is running in the same mode after tidinfo as before.

Getting More Help

help
Prints a list of different categories of commands.

help CATEGORY
Prints a list of commands within the CATEGORY.

help COMMNAD
Prints help information about the COMMAND

list-namespaces
Displays a list of all objects (parts of the simulation environment). If you don't know where some piece of simulation state is stored, this may help you find it. To learn more about a namespace of interest, type its name and hit the Tab key one or more times. For example, you may inspect the real-time clock (calendar chip) object by typing rtc0 and hitting Tab twice. Then you can use the help command to learn more about the indicated methods of the rtc0 object.

Reality Check

By the time you're working on the kernel project, you should be using at least these commands, or you are wasting precious debugging time.

  • stack-trace
  • psym
  • pregs
  • break
  • x
  • list -s
  • cpu0_tlb.info/cpu0_tlb.status and cpu0.tablewalk

[Last modified Thursday September 07, 2023]