Debugging
Debugging messages
MyJIT contains several tools simplifying development. One of them is the msg operation which prints out the given message or a value of the given register. The msg operation has one or two operands. The first one is always an immediate value which is the string to display. The second operand is optional and it must be a register. In this case the first string serves as the format string for printf and the value of the register is printed out using this string. The example of the msg operation usage:
jit_msg(jit, "Simple message\n"); jit_msgr(jit, "Reg 1: %l\n", R(1));
Warnings
One of the MyJIT's goals is to achieve maximal performance while emitting code. Thus, it does not do many checks while generating machine code from the intermediate language. Therefore, if the code in the intermediate language contains an error, it leads to a faulty machine code, and subsequently to a crash of the program. In order to avoid such errors, MyJIT contains a function:
void jit_check_code(struct jit *jit, int warnings);
Which can be called before code generation and which can point out to the most common errors. In the second argument you may specify if you want to be warned about all types of errors (JIT_WARN_ALL) or you can pick only some of them from the following list:
- JIT_WARN_DEAD_CODE -- detects unreachable code
- JIT_WARN_OP_WITHOUT_EFFECT -- displays warnings about operations without effect
- JIT_WARN_INVALID_DATA_SIZE -- displays warning if the size operand does not contain a valid value (i.e., 1, 2, 4, or 8)
- JIT_WARN_UNINITIALIZED_REG -- displays warning if an uninitialized register is used
- JIT_WARN_REGISTER_TYPE_MISMATCH -- displays warning if a general purpose register is used in place where the floating point register is expected, or vice versa
- JIT_WARN_MISSING_PATCH -- reports all jump operations with a JIT_FORWARD declaration but without corresponding patch
- JIT_WARN_UNALIGNED_CODE -- displays warning if the code follows data section without alignment
- JIT_WARN_INVALID_CODE_REFERENCE -- displays warning if ref_code or data_code is referring to a data and not to a valid code
- JIT_WARN_INVALID_DATA_REFERENCE -- displays warning if ref_data or data_data is referring to a code and not to a data
- JIT_WARN_ALL -- displays all warnings
Code listing
In real programs is MyJIT typically called from various functions and code is constructed in several steps, thus it is sometimes difficult to figure out, how the code looks like. Therefore, MyJIT provides several means allowing to inspect final code in the intermediate language as well as in the machine code. This functionality is provided through the jit_dump_ops function. In the second argument you may specify if you want to list:
- list of all operations in the intermediate language (JIT_DEBUG_OPS)
- generated machine code (JIT_DEBUG_CODE)
- combination of both -- MyJIT operations and machine code (JIT_DEBUG_COMBINED)
To make the navigation through the listing easier, we have included one auxiliary operation:
comment imm
Which has only one argument -- string which will appear only in the dumps.
NOTICE! Do not use debugging operations and functions in the production code. These operations are not efficient and may lead to a poor performance. You should rather call the printf function explicitly. The jit_dump_ops with the JIT_DEBUG_CODE is using gcc and objdump to disassemble the code, therefore, these two programs have to be present in the system, or, on OS X clang and otool are used. The JIT_DEBUG_COMBINED option requires myjit-disasm disassembler in the directory along with the debugged program, or the path to the disassembler has to be specified in the MYJIT_DISASM environment variable.
Examples of the outputs for the above mentioned source code.
Example of the IL listing (JIT_DEBUG_OPS)
prolog 0xbfe62858 declarg integer, 0x4 getarg r0, 0x0 addi r1, r0, 0x1 retr r1
Example of the machine code listing (JIT_DEBUG_CODE)
0000000000000000 <main>: 0: 55 push rbp 1: 48 8b ec mov rbp,rsp 4: 48 83 ec 20 sub rsp,0x20 8: 48 8b f7 mov rsi,rdi b: 48 8d 46 01 lea rax,[rsi+0x1] f: 48 8b e5 mov rsp,rbp 12: 5d pop rbp 13: c3 ret
Example of the combined listing (JIT_DEBUG_COMBINED)
prolog 0x7fffa0371db0 0000: 55 push rbp 0001: 48 8b ec mov rbp, rsp 0004: 48 83 ec 20 sub rsp, 0x20 declare_arg integer, 0x8 getarg r0, 0x0 0008: 48 8b f7 mov rsi, rdi addi r1, r0, 0x1 000b: 48 8d 46 01 lea rax, [rsi+0x1] retr r1 000f: 48 8b e5 mov rsp, rbp 0012: 5d pop rbp 0013: c3 ret