
\chapter{Debugging}
\label{ch-debugging}

{\small
\begin{flushright}
Documentation: Cristina [Nov 2000], based on Mike's content
\end{flushright}
}


The UQBT framework does not provide much support for debugging per se.  
Graphs are generated to determine the flow of control of the program, 
and start of basic block virtual memory addresses are generated in the 
low-level C code.  
These facilities help you to map the generated code to the original 
assembly code; however, one still needs to be able to determine 
the source of a bug.
In this chapter we present techniques that helps locate a bug. 
We use the gdb debugger.  All examples are in terms of SPARC code. 


\section{Simple debugging techniques}
The most common debugging technique is to emit printf's in the 
generated low-level C code as well as in the original source program 
(if you can recompile it).  This helps determine which area of the 
program needs to be looked at in more detail.  

You can also edit binaries themselves.  This can allow you to, e.g., 
add a printf statement in the source binary (even when you do not
have the source code for it and therefore you cannot recompile it
with the printf statement).   
There is information in Mike's page on how to do this 
(http://www.csee.uq.edu.au/~emmerik).


\section{How to view the contents of a register transfer}
Given a pointer to a register transfer (RT), pRT, we can view its address 
and its contents by emitting the following commands: 
\begin{verbatim}
   p pRT            /* Just look at the pointer and its type */
   p *pRT           /* Look at the whole object */ 
\end{verbatim}
The complete contents of an RT can be viewed by casting the pointer 
to a pointer to the correct derived type of the RT.  If, for example, 
pRT is known to point to an assignment RT, then we can view the contents 
of all the fields of an assignment RT by emitting the following command
\begin{verbatim}
   p *(RTAssgn*)pRT
\end{verbatim}
The actual type of an object can often be found by noting the annotation 
of the virtual table, e.g., when using \verb!p *pRT!, one notes 
``RTAssgn virtual table''. 

We can then view individual fields of that RT by using the ``dot'' 
notation.  If the previous command provided the result in statement 4, 
then we can use that reference in our command.  In the following 
example, we want to see the left-hand side field of the assignment RT 
returned in statement 4: 
\begin{verbatim}
   p $4.pLHS
\end{verbatim}
which will display the address of the pointer pLHS as well as its type: 
\begin{verbatim}
   $7 = (SemStr*)0xabcd
\end{verbatim}
We can then view the contents of this semantic string by using the 
print routine provided in the SemStr class: 
\begin{verbatim}
   call $7->print(cerr)
\end{verbatim}
Most UQBT objects from BasicBLocks and SemStrs have a print method 
which can be used in this way.  Note that displaying the contents of 
RTlists requires the use of ``print(cerr,0)''. 


\section{How to step through a binary with no debug symbols}
The original binary that you are translating may not include debug symbols,
however, a useful debugging technique is to test the output of the source 
program at several points against that output of the generated program 
(e.g. the end of known routines, to determine if the same result is being 
returned).  You can easily remake your target program to include symbols, 
but not your source program.  The following are useful tips: 

\begin{itemize}
\item On SPARC processors, code normally starts at address 0x10000 and the 
  page size is 8 to 64Kb in size.  If the code starts at 0x10000, then most
  likely the read/write data starts at at least 0x20000.

\item You can display the disassembly of the first $n$ instructions of a 
  routine by using the \texttt{x} command.  In the following example we 
  display the first 20 instructions of the routine ran2.  Note that even 
  though there are no debug symbols in the binary, some of the routine 
  names get stored in the dynamic symbol table, and hence the debugger has 
  a way to get at these names.  
  \begin{verbatim}
  x/20i ran2
  \end{verbatim}

\item You can set a breakpoint at any address by using the break command 
  (\verb!b!) with the address dereference operator.  In the following 
  example, we set a breakpoint at address 0x12624: 
  \begin{verbatim}
  b *0x12624
  \end{verbatim}

  You can then step through the instructions by using the next instruction 
  (\verb!ni!) and step instruction (\verb!si!) commands. 
  You will not see a disassembly of the instruction as you step, 
  therefore first disassemble about 20 instructions to know where you are. 

\item You can also inspect the contents of a register by using the 
  \verb!regi! option of the \verb!info! command, and specifying the 
  particular register of interest.  For example, if we want to determine
  the contents of the floating point register 2, \verb!f2!, we would emit: 
  \begin{verbatim}
  info regi f2
  \end{verbatim}
  The debugger will display the contents of a float register in terms of 
  its single precision, its raw value (i.e. the bits interpreted as an 
  integer, but displayed in hex) and its double precision, e.g: 
  \begin{verbatim}
  f2  14.9999  (raw 0x41...)  1677215
  \end{verbatim}
  The double precision value for \verb!f2! is the combination of registers
  \verb!f2! and \verb!f3!.  If the register number is odd, the double 
  precision value is not displayed, as double floats should start at 
  even-numbered registers. 
\end{itemize}


\section{Debugging in parallel - source and target binaries}
In order to determine where the source and target programs diverge, one 
can run procedures and stop at the end of them to determine what value
gets returned from each.  If you set a breakpoint on a procedure, you  
can then tell the debugger to run until the end of the procedure and then
display the contents of a particular register, e.g.
\begin{verbatim}
  fini
  info regi f0
\end{verbatim}

You can also attach the previous series of commands to a particular 
breakpoint so that they get executed each time the debugger breaks 
at that breakpoint.  If we want to attach the previous two commands 
to the second breakpoint, we need to emit the following code (note 
the last \verb!end! command): 
\begin{verbatim}
  command 2
  > fini
  > info regi f0
  > end
\end{verbatim}

You may want to use a temporary breakpoint in a particular routine; 
temporary breakpoints are only valid for one run (i.e. they are 
deleted once hit): 
\begin{verbatim}
  tbreak *0x12578
\end{verbatim}

When you have loops and you are looking for a particular value, 
you can set a conditional breakpoint.  If you want to have a 
breakpoint on line 54 (say this sets your fifth breakpoint) and 
you want to stop the execution when register r4 is not zero, 
you could emit the following commands: 
\begin{verbatim}
  b 54
  condition 5 r4!=0
\end{verbatim}



\section{Other tips}
There is nothing better than knowing the original source program,
i.e. becoming familiar with the source program's source code and 
what it does, in order to determine where the translation can go 
wrong.  

You can use \verb!objdump! to determine the address of the different 
sections in the source binary, e.g. to find out what section a 
particular address belongs to.  For example
\begin{verbatim}
  objdump -h file
\end{verbatim}

You can use \verb!objdump! to dump the contents of a section. 
For example, to disasemble the .rela.bss section of the program 
compress95, you can do: 
\begin{verbatim}
  objdump -s -j .rela.bss compress95
\end{verbatim}

If you want to look at the detailed contents in a given section, 
you can use \verb!elfdump!.  This prints Elf file information in 
a symbolic form.   For example, to look at the symbols of the 
compress95 program, we emit: 
\begin{verbatim}
  elfdump compress95 | less
\end{verbatim}

If you are looking for patterns that require inspection, say in the 
generated code, you can use \verb!grep!.  For example, if you are 
looking for double precision floats being assigned (single precision)
float values in the range 64 to 79, you can emit: 
\begin{verbatim}
  d[0-9][0-9]=(f
\end{verbatim}


\section{Current known problems}
The following is a list of known problems, as at Nov 1st, 2000: 

\begin{itemize}
\item Floating point values passed in integer registers for parameter passing 
  purposes on SPARC code.  

\item Overlapping registers: doubles on SPARC and al/ax/eax on x86.  
  Currently, these overlapping registers take different indexes into the
  register pool, without the dependencies between them being taken into 
  account.  

\item If a \verb!_locals-k! type of code is emitted in the generated 
  code, it means that there was a push statement in the source assembly 
  code that was not transformed/removed through analysis.  Typically, 
  pushes on x86 code are used for parameter passing, setting up the
  stack frame, spilling of registers, and copying registers to the 
  stack as a handy temporary location.  The first two cases are 
  supported at present. 

\item Alignment of doubles for x86 code (doubles are aligned on 4-byte 
  boundaries on x86 whereas they are aligned on 8-byte boundaries on 
  SPARC code).

\item Setting a register to 0 through the use of an xor instruction should 
  not appear as a use of a register, i.e. 
  \begin{verbatim}
  xor r,r
  \end{verbatim}
  should be replaced by
  \begin{verbatim}
  r = 0
  \end{verbatim}

\item Endianness differences and passing parameters to library functions 
  that are pointers to data.  In this case, the data may not be swapped 
  as needed. 

\item The code that implements pointers to functions has not been fully 
  tested. 

\item The passing of doubles to varargs routines in the presence of 
  endianness differences from a source SPARC binary, will pass two 
  32-bit values that are individually swapped, but for which the two 
  halves have not been swapped.  

\end{itemize}
