Showing posts with label GDB. Show all posts
Showing posts with label GDB. Show all posts

Leak Tracer vs valgrind for memory leak analysis of a C++ project


Attaching a large project to leak tracer is faster than valgrind.
How to use leaktracer and valgrind step by step:
A memory leaking program which would be used to check for memory leak using LeakTracer.
#include<iostream>
using namespace std;
#include<unistd.h>
int main()
{
char* name = new char[20];//allocates 20 bytes
//delete[] name;//Now leaks 20 byte
//sleep (30);
return 0;
} 
------------------------STEPS to use LeakTracer----------

STEP-0: Compile with -g flag to capture gdb debugging symbols.
    g++ -g leakProgram.cpp
    Here "a.out" would be my application in which I want check memory leak

STEP-1: run command "LeakCheck" with your application, here a.out
    /usr/bin/LeakCheck /home/admin/a.out

STEP-2: run command "leak-analyze" with your application and generated file leak.out
    /usr/bin/leak-analyze a.out /home/admin/leak.out

----------------------------Example----------------------------
Ubuntu:~/$ g++ -g leakProgram.cpp
Ubuntu:~/$ /usr/bin/LeakCheck /home/admin/a.out
Ubuntu:~/$ /usr/bin/leak-analyze a.out /home/admin/leak.out
Gathered 1 (1 unique) points of data.
Reading symbols from a.out...done.
(gdb)
#-- Leak: counted 1x / total Size: 20
0x80485c2 is in main() (leakProgram.cpp:6).
5    {
6    char* name = new char[20];//allocates 20 bytes but not freed.


--------------------STEPS to use Valigrind----------
Ubuntu:~$ valgrind --tool=memcheck --leak-check=yes ./a.out
==6829== Memcheck, a memory error detector
==6829== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==6829== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==6829== Command: ./a.out
==6829==
==6829==
==6829== HEAP SUMMARY:
==6829==     in use at exit: 20 bytes in 1 blocks
==6829==   total heap usage: 1 allocs, 0 frees, 20 bytes allocated
==6829==
==6829== 20 bytes in 1 blocks are definitely lost in loss record 1 of 1
==6829==    at 0x402ADFC: operator new[](unsigned int) (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==6829==    by 0x80485C1: main (leakProgram.cpp:6)
==6829==
==6829== LEAK SUMMARY:
==6829==    definitely lost: 20 bytes in 1 blocks
==6829==    indirectly lost: 0 bytes in 0 blocks
==6829==      possibly lost: 0 bytes in 0 blocks
==6829==    still reachable: 0 bytes in 0 blocks
==6829==         suppressed: 0 bytes in 0 blocks
==6829==
==6829== For counts of detected and suppressed errors, rerun with: -v
==6829== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

CMakeLists.txt and cmake interview questions

Common GDB Debugging Question

How to attach gdb with running process

Remote Debugging using gdb

How to debug multi threaded application using gdb

Advance debugging C/C++ code in GDB in Linux

You may also like:

  Singleton Design Pattern example in C++


 

CMakeLists.txt and cmake interview questions

 

 

How to attach gdb with running process

How to attach gdb with running process ?
gdb <PROCESS NAME> <PROCESS ID>
 we can grab the process id with ps command.
Suppose your program name is a.out
so command to get the process id would be?
ps -elf | grep a.out
usr1   4473  3529  0 16:42 pts/0    00:00:00 grep --color=auto a.out
here process name is a.out and process id is 4473
so command to attach the running process a.out with process id a.out would be
gdb a.out 4473
Note: You might require to execute as sudo user.

You may also like:

Remote Debugging using gdb

Q) How to do Remote Debugging using gdb?
1) On host machine Start a gdbserver and 2) Connect gdb from Host Machine to remote gdbserver
1) Start a gdbserver:
On Host Machine start gdbserver with application to debug on a specified IP and Port i.e.
gdbserver <IP>:<PORT> <APPLICATION>
e.g.
gdbserver 192.168.1.8:8082 Debug/Dummy
Output:
Process Debug/Dummy created; pid = 3523
Listening on port 8082
It will start the gdbserver for application “Dummy” on port 8082 and will wait for a host to connect to this on port 8082.

2.) Connect gdb from Host Machine to remote gdbserver

From the Host Machine start gdb and execute following command on gdb command prompt
target remote <TARGET MACHINE IP>:<GDBSERVER PORT>
eg
(gdb) target remote 192.168.1.8:8082
It will connect this gdb from Host Machine to remote gdbserver running on Target Machine. Now on Host Machine it will show a gdb command prompt.
output:
Remote debugging using 192.168.1.8:8082
warning: Could not load vsyscall page because no executable was specified
try using the "file" command first.
0x00007ffff7dd9cd0 in ?? ()
(gdb)
Now gdb from Host Machine is connected to target Machine’s gdbserver. Press “c” to continue debugging,
(gdb) c

CMakeLists.txt and cmake interview questions

How to debug multi threaded application using gdb

Q) How to debug a multi threaded application?
NOTE: "ulimit -c unlimited" command to set unlimited size for large core dump generation.
NOTE: "g++ thread1.cpp -g -lpthread" command to compile thread1.cpp file with pthread library.
NOTE: "break funcion_name or filename:line", "run","continue","step","list","print","attach -c core appNmae","bt", "thread apply all bt", "info thread", "thread thread id","bt","quit".
NOTE: step executes a function as a single instruction and continue stepinto the function definition of function.
Command to debug a core file core:
attach the core file and application that has dump the code and take the bt.
"gdb -c core ./a.out"

Then it will show function causing the core dump was called by which thread by seeing start_thread(arg=0xb6bedb40).
Here 0xb6bedb40 is the thread id.

Then run the commands: "info thread" to see the culprit thread "0xb6bedb40"'s stack id.
In this case culprit thread is "0xb6bedb40",whose thread stack id is 3.
So either we can switch to third thread by command "thread 3", and take bt of the third thread only by command "bt" or
we can take stack of all the threads by "thread apply all bt". and use the stack of the thread 3 only to debug or
In this case line at thread1.cpp:37 caused the crashed by thread 3 so we can take bt of "thread 3"
Detailed steps:
-----------------
(gdb) bt //STEP:1
#0  0x08048b3c in odd (o=0x0) at thread1.cpp:37
#1  0xb76f3f70 in start_thread (arg=0xb6bedb40) at pthread_create.c:312
#2  0xb754170e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:129
(gdb) info thread //STEP:2
  Id   Target Id         Frame
  3    Thread 0xb73eeb40 (LWP 15708) 0xb7723424 in __kernel_vsyscall ()
  2    Thread 0xb73f0700 (LWP 15707) 0xb7723424 in __kernel_vsyscall ()
* 1    Thread 0xb6bedb40 (LWP 15709) 0x08048b3c in odd (o=0x0) at thread1.cpp:37
(gdb) thread 3 //STEP:4
[Switching to thread 3 (Thread 0xb73eeb40 (LWP 15708))]
#0  0xb7723424 in __kernel_vsyscall ()
(gdb) bt //STEP:5
#0  0xb7723424 in __kernel_vsyscall ()
#1  0xb76f7d4b in pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/i386/i686/../i486/pthread_cond_wait.S:187
#2  0x08048a3b in even (v=0x0) at thread1.cpp:17
#3  0xb76f3f70 in start_thread (arg=0xb73eeb40) at pthread_create.c:312
#4  0xb754170e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:129
(gdb) thread apply all bt //STEP:5

Thread 3 (Thread 0xb73eeb40 (LWP 15708)):
#0  0xb7723424 in __kernel_vsyscall ()
#1  0xb76f7d4b in pthread_cond_wait@@GLIBC_2.3.2 () at ../nptl/sysdeps/unix/sysv/linux/i386/i686/../i486/pthread_cond_wait.S:187
#2  0x08048a3b in even (v=0x0) at thread1.cpp:17
#3  0xb76f3f70 in start_thread (arg=0xb73eeb40) at pthread_create.c:312
#4  0xb754170e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:129

Thread 2 (Thread 0xb73f0700 (LWP 15707)):
#0  0xb7723424 in __kernel_vsyscall ()
#1  0xb76f5178 in pthread_join (threadid=3074353984, thread_return=0x0) at pthread_join.c:92
#2  0x08048c51 in main () at thread1.cpp:54

Thread 1 (Thread 0xb6bedb40 (LWP 15709)):
#0  0x08048b3c in odd (o=0x0) at thread1.cpp:37
#1  0xb76f3f70 in start_thread (arg=0xb6bedb40) at pthread_create.c:312
#2  0xb754170e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:129



Q) How to skip 20 lines and show next 10 lines:
list +20,+10

if list shows lines upto 52 then list +20,+10
will displays 10 lines after the line from 72(52+20).
ie it display line 72 to 82

Q) Program using two threads to print odd and even. In each thread function I have knowngly introduced dived by zero error. Need to debug which thread is causing the divide by zero error first and dump core and optimize the code for that thread accordingly.
//Improved Example synchronized using mutex and conditional variable.
#include<iostream>
using namespace std;
#include<stdio.h>
int count=0;
int maxx=10;
pthread_mutex_t mutex;
pthread_cond_t cond;
void* even(void *v)
{
    //cout<<"even thread"<<endl;
    while(count<maxx)
    {
        pthread_mutex_lock(&mutex);//lock before checking
        while((count%2)!=0)
        {
            pthread_cond_wait(&cond,&mutex);//wait until count becomes odd
            //it releases the mutex and it waits till condition cond is signaled as complete and mutex is available.
        }
    if(count==6){printf("%d",count/0);}
        cout<<"even "<<count++<<endl;
        pthread_mutex_unlock(&mutex);//release
        pthread_cond_signal(&cond);//signal to another thread
    }
    pthread_exit(0);//pthread_exit is called from the thread itself to terminate its execution (and return a result) early.
}
void* odd(void *o)
{
    while(count<maxx)
    {

        pthread_mutex_lock(&mutex);//lock before checking
        while((count%2)!=1)
        {
            pthread_cond_wait(&cond,&mutex);//wait until count becomes odd
        }
    if(count==5){printf("%d",count/0);}
        cout<<"odd "<<count++<<endl;
        pthread_mutex_unlock(&mutex);//release
        pthread_cond_signal(&cond);//signal to another thread
    }
    pthread_exit(0);
}
int main()
{
    pthread_t t1;
    pthread_t t2;

    pthread_mutex_init(&mutex, 0);
    pthread_cond_init(&cond, 0);

    pthread_create(&t1,NULL,&even,NULL);
    pthread_create(&t2,NULL,&odd,NULL);
    pthread_join(t1,0);
    pthread_join(t2,0);

    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);

    //pthread_join is called from another thread to wait for a thread to terminate and obtain its return value
    cout<<endl;
    return 0;
}
-----------------------------------------------
Q) Ho to debug multi-threading Applications with gdb debugger?
Compiling Multi-threaded Code using g++ with Debug Info
g++ -g --std=c++11 -pthread sample.cpp -o sample

Q)How to List all active threads?
“info threads”

Q)How to Check Stack trace of threads ?
In non multi threading applications there is only one thread i.e. main function. Therefore, to check the stacktrace we use command “bt”.
But in multi threading applications, as there are many threads and each threads has its own stack.
But “bt” command will display the stack trace of current active thread only. Now what if want to inspect stacktrace of all the threads at same point ?
To display the stack trace of all the threads use following command
(gdb) thread apply all bt

//output would be

Thread 3 (Thread 0xb74a8b40 (LWP 4335)):

#0  __GI___nptl_death_event () at events.c:31
#1  0xb7faf104 in start_thread (arg=0xb74a8b40) at pthread_create.c:363
#2  0xb7dfc70e in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:129

Thread 1 (Thread 0xb7cab700 (LWP 4330)):

#0  main () at threadOddEven.cpp:17
(gdb)


Q) How to Switch between threads while debugging?
(gdb) thread <Thread Number>
(gdb) thread 2
(gdb) thread 1

CMakeLists.txt and cmake interview questions

Advance debugging C/C++ code in GDB in Linux

The purpose of a debugger is to allow us to see what is going on inside our C/C++ program while it runs. In addition, we can use gdb to see what our program was doing at the moment it crashed.
Task that gdb can perform:
Start your program and step through it line by line
  • Make your program stop on specified conditions
  • Show the values of variables used by your program
  • Examine the contents of any frame on the call stack
  • Set breakpoints that will stop your program when it reaches a certain point. Then you can step through part of the execution using step and next,
  • and type continue to resume regular execution.
  • For C and C++ programs, gdb and ddd are debuggers that you can use. ddd is a easy-to-use GUI wrapper around an inferior debugger (gdb for GNU
  • compiled C or C++ code). ddd allows you to interact with the debugger by using either GUI menu options or the under-lying debugger's command line
  • interface. In addition, ddd automatically displays source code when breakpoints are reached.
Commonly used gdb commands
  • gdb also understands abreviations of commands, so you can just type up to
  • the unique part of a command name ("cont" for "continue", or "p" for "print")
  • help # List classes of all gdb commands
  • help <topic> # Shows help available for topic or command
  • where (or bt) # Shows stack: sequence of function calls executed so far
  • # (good for pinpointing location of a program crash)
  • frame # Shows all stack frames
  • frame <frame-num> # Sets current stack frame to <frame-num>
  • # (useful for checking parameter and argument values)
  • run # Starts program execution from the beginning
  • break <line> # Sets breakpoint at line number <line>
  • break <func-name> # Sets breakpoint at beginning of named function
  • continue # Continues execution from breakpoint
  • condition <bp-num> <exp> # Set breakpoint <bp-num> to
  • # break only when <exp> is true
  • info break # Shows current breakpoints
  • disable [breakpoints] # [bnums ...] Disable one or more breakpoints
  • enable [breakpoints] # [bnums ...] Enable one or more breakpoints
  • clear <line> # Clears breakpoint at line number <line>
  • delete <bp-num> # Deletes breakpoint number <bp-num>
  • delete # Deletes all breakpoints
  • step (or s) # Executes next line of program (steping into functions)
  • step <count> # Executes next <count> lines of program
  • next (or n) # Like step, but treats a function call as a single instr
  • until <line> # Executes program until line number <line>
  • print <exp> (or inspect <exp> # Displays the value of expression <exp>
  • display <exp> # Automatic display of <exp> each time a breakpt hit
  • whatis <exp> # Shows data type of expression <exp>
  • info locals # Shows local variables in current stack frame
  • set variable <variable> = <exp> # Sets variable <variable> to expression <exp>
  • list # Lists next few lines of program
  • list <line> # Lists lines around line number <line> of program
  • list <start> <end> # Lists line numbers <start> through <end>
  • list <func-name> # Lists lines at beginning of function <func-name>
  • help status # lists a bunch of info X commands, including:
  • info frame # list information about the current stack frame
  • info locals # list local variable values of current stack frame
  • info args # list argument values of current stack frame
  • info registers # list register values
  • quit # quits gdb
Compile, run, attach to running program:
(1) always compile .o and executable files with -g
% gcc -g -o myprog main.c
 of course you should always use a Makefile and add -g to the build rules 
or for cs21 if you compile with the gccx compiler it automatically 
inculdes the -g flag for you

(2) to start a program in the debugger
% gdb ./a.out
% ddd ./a.out   # ddd is the GUI interface to gdb
you will get the gdb prompt before it starts executing myprog code
you can add breakpoints here, then start program running
(gdb) run
OR if myprog has command line arguments
(gdb) run arg1 arg2 ... argn

(3) to attach gdb to an already running program
(a) get the process id, pid, for the program
for example, to get the pid of my infiniteloop process:
% ls
PID TTY          TIME CMD
15586 pts/15   00:00:00 tcsh
29390 pts/15   00:00:01 infiniteloop
(b) attach gdb to it 
Two was: 
(1) start new gdb specifying pid 
gdb executable name <pid>
$ gdb infiniteloop  29390 
 (2) from within gdb use attach command
attach <pid>
$ gdb infiniteloop
(gdb) attach 29390 
courtesy: