How to analyze issue without source code

Run time tracing allows the debugger to identify the problem on executable. This technique shall also be used to understand the code flow of the program. There are tools which traces all system calls or library routines.

strace utility provides the capability to trace the execution of an application from the perspective of system calls. Along with the system call routine, it also displays their arguments, return value, etc

Linux permits to access 4 GB virtual address space for a process and that 4 GB virtual space is divided into two parts such as user space ( 3 GB) and kernel space (1 GB). When we run any application program along with library , they allocates memory from user space . Here in the following example printf is a library function and internally uses a standard library libc.so. The function printf writes data “Hello” into monitor , but how it happens.

Ex.

void main()

{

printf(“Hello”);

}

 

Operating system uses system call to copy the data from user space to kernel space and write into device file which is associated with a device ( example stdout for monitor) . The driver known as modules works in kernel space which reads the data from a device file and write into the port .

 

To list out the system call maintained by o/s there is a development tool called strace .Ittrace the system calls and signals . It intercepts and records the system calls made by a running process. strace can print a record of each system call, its arguments, and its return value. strace is a system call tracer, i.e. a debugging tool which prints out a trace of all the system calls .

$strace ./singo

output:

 

open(“/etc/ld.so.cache”, O_RDONLY) = 3

fstat64(3, {st_mode=S_IFREG|0644, st_size=111023, …}) = 0

mmap2(NULL, 111023, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f91000

close(3) = 0

open(“/lib/libc.so.6”, O_RDONLY) = 3

read(3, “\177ELF\1\1\1\3\3\1\360\3247004″…, 512) = 512

write(1, “Hello”, 5Hello) = 5

Each line starts with a system call name, is followed by its arguments in the parenthesis & then has return value at the end of the line. The important system call made in the above output are open,close,read,write. The last line write(1, “Hello”, 5Hello) = 5 line corresponding to the system call that cause Hello to be printed on the screen. The first argument -1 is the file descriptor of the file i.e. stdout to write to. So it writes the message on the terminal instead of writing in some other file on disk. The second argument tells the data is a string & third argument display the total number of character in the string.

$ strace -c ./singo

Hello% time seconds usecs/call calls errors syscall

—— ———– ———– ——— ——— —————-

nan 0.000000 0 1 read

nan 0.000000 0 1 write

nan 0.000000 0 2 open

nan 0.000000 0 2 close

nan 0.000000 0 1 execve

nan 0.000000 0 1 1 access

nan 0.000000 0 1 brk

nan 0.000000 0 1 munmap

nan 0.000000 0 2 mprotect

nan 0.000000 0 7 mmap2

nan 0.000000 0 3 fstat64

nan 0.000000 0 1 set_thread_area

—— ———– ———– ——— ——— —————-

100.00 0.000000 23 1 total

 

From the above output, it is evident that write system call is used 1time. This is initiated by printf() statement on stdout file descriptor.

One another important option of strace is -tt, it causes strace to print out the time at which each call finished.

Library Tracing with ltrace

ltrace allows tracing any library function calls. It traces not only libc.so, but also any third party libraries.

To run ltrace on the executable ‘test’ created in the previous section, run

$ltrace ./test
It displays the following

__libc_start_main(0x80484c4, 1, 0xbfea17f4, 0x8048570, 0x8048560 <unfinished …>
fopen(“info.txt”, “r”)                                                                           = 0x8a03008
fgets(“1\n”, 80, 0x8a03008)                                                                      = 0xbfea16fc
printf(“Line %d: %s”, 4568017, “1\n”Line 4568017: 1
)                                                            = 16
—more output—-

fgets(“10\n”, 80, 0x8a03008)                                                                     = 0xbfea16fc
printf(“Line %d: %s”, 4568026, “10\n”Line 4568026: 10
)                                                           = 17
fgets(“10\n”, 80, 0x8a03008)                                                                     = NULL
fclose(0x8a03008)                                                                                = 0
+++ exited (status 0) +++
Without the source code, we can understand that fgets and printf functions are used heavily by this executable. We can try to optimize the code to reduce cpu cycles.

Most of the option present in strace is also present in ltrace. For the complete set of options run `man ltrace`.