Wednesday, April 18, 2012

Finding memory leaks easily with Solaris Discovery tool


For every beginner level C/C++ developer memory leaks are the most troublesome bug to detect. I have used mdb, solaris sun studio 12 but couldnt successfully find memory leaks. Then googled and heard a tool called Discover which is aviable in Solaris express (may be in other nix aswell). It is such a cool tool in that you don't need to configure it manually, or eats up memory when running or represents data in almost cryptic memory addresses and stuff. When ran with the application, it provides the function/methos in which the leaking occurs and from that point onwards troubleshooting becomes much easier.

All you have to do is,

1. compile your app with lumem
    g++ app.cpp -lumem
2. type discover app
     #discover app
3.run app
     # ./app arg1.

and then when application exists a cool html page named app.html wiil be created in the same directory. If you are running the app again make sure to recompile and to issue 'discover app' command again before running app.

Thursday, April 12, 2012

Using Solaris 11 express mdb to debug your C/C++ application

Hello everyone,

Im today going to share about how to use Solaris express Module Debugger to find stack trace when an application crashes and also how to find memory leaks using it.

First make sure mdb is installed,
# pkg list | grep mdb
developer/debug/mdb                               0.5.11-0.151.0.1           i--

If not try installing it. (pkg install mdb)
Now you are all set to go ! IF you are using gcc/g++ instead of  C/C++ IDE's then you would've wondered how to find a cause to a certain types of run time errors,
eg:- segmentation fault, buss error, aborted...etc

Well mdb can help you with it ! in above mentioned cases, the core ( a snapshot of memory content when error occurred) gets dumped. mdb can be used to analyze this core file.

# mdb core
Loading modules: [ libumem.so.1 libc.so.1 ld.so.1 ]
> ::stack

you can now view the stack when program crashed by issuiing command 'stack' prefixed with double colons ,

# mdb core
Loading modules: [ libumem.so.1 libc.so.1 ld.so.1 ]
> ::stack
libc.so.1`_lwp_kill+8(6, ff0c8ca8, fe85ca10, 0, 0, fe85c000)
libumem.so.1`umem_do_abort+0x1c(fe848354, 14, 5, fe85c000, fec7b990, 6)
libumem.so.1`umem_err_recoverable+0x78(fe849584, fe85c000, 1, fe85f0dc, a, a)
libumem.so.1`process_free+0xf8(79e1c, 1, deadbc00, 3e3a1000, 79ccb, 3b7cc)
_Z16houseKeepingExitPcS_iPPhPP8IMSI_VLRPiPSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEES5_P14_pthread_mutexPS5_+0x118(28088, 79e2c, 6, fec7bf88, fec7bd68, fec7bd7c)
_Z12handleClientP18client_thread_args+0x954(ffbffa80, 0, 0, fefb1240, 246fc, 0)
libc.so.1`_lwp_start(0, 0, 0, 0, 0, 0)
>
as you can see  'houseKeepingExit' function has called 'process_free' which is actually called when you call free() to release dynamically allocated memory.

for a complete list of dcmds commands type,
::dcmds

When you are finished you can exit by typing '::quit'.

To find prevaling memory leaks, we have to use '::findleaks' dcmds command. But prior to using it we have to set enviroment variables,

 LD_PRELOAD=libumem.so and UMEM_DEBUG=default

(don't set LD_PRELOAD with the entire  path of libumem  as it would give wrong ELF class errors)
When compiling our application we have to link with libumem.so (-lumem) as follows,

eg:
     #g++ test.cpp -lnsl -lumem

Finally we can run the application. If it encounters a memory leak app will exit with a abort dumping the core file or else After running app, we note down the pid of the app using pgrep and issue gcore to dump a core file,

eg:-
  #pgrep test
123
#gcore 123
gcore: core.123 dumped

now use mdb,

# mdb core
Loading modules: [ libumem.so.1 libc.so.1 ld.so.1 ]
> ::findleaks
findleaks: no memory leaks detected
>

You can read the following articale from Oracle site, which provides more details about troublshooting memory issues with mdb,

http://developers.sun.com/solaris/articles/libumem_library.html


Tuesday, March 27, 2012

C++: Imlpementing a PHP styled, timeout enabled,Socket wrapper funtion for C/C++ accept()


I'm relatively new to C++ and learning it was a tougher challenge (i'm still learning it by the way ;)) than learning other "newer" languages, it really surprised me that a developer should go out of his way to implement even the most trivial functionsin order to achieve his main objective, which is in violation with the concept of OOP and encapsulation.  With so many seasoned veterans using C/C++ around, I wonder how they all turn a blind eye to this issue.

     A recent project i did required me to implement a socket server that keeps listening for an incoming connection, if a request arrives within a certain time window it  should serve it else  should timeout and proceed with a little bit of housekeeping after which it should loop back to socket accept. But when implementing this i had much trouble trying to figure out how to find a way to set timeout on accept().
I found a piece of code in Solaris programming interfaces guide which offered a method (platform used for the project is Solaris)
(docs.oracle.com/cd/E19253-01/817-4415/817-4415.pdf)

Timeout is achieved using select() function, which allows us to instruct kernel to wait for any one of multiple event to occur and proceed once one or more events had happened. I wanted a PHP style accept() function  for C++ so i modified the version given in the above document to create wrapper function for C++ accept() called socket_accept() as below.



 The timeout is a timeval type structure pointer passed to it by the caller. Following code shows how it should be defined(5 seconds and 0 micro seconds).



and then call it in main() as below,




Sunday, November 13, 2011

Oracle Database: Loading data using SQLLDR part I

(tested on Oracle 11G , Solaris 11 express, Sun v240 server platform.)

Imagine you have millions of records in a file that needs to be inserted into a table (as typically the scenario in data warehousing applications). How are you going to load data in ? There are three ways to go about this,

1. Using insert statements separately for every record; you can either create a insert command batch file and run on sqlplus/ or using a programming language by opening a connection to database and inserting data. (this is good for several hundred records ? but since we are talking about millions of records this method is highly inefficient in terms of resources and time taken)

2. Using bulk inserts; some programming languages provide a batch loading API in their database connector. For instance in JAVA JDBC one can use statements.addBatch() or even better preparedStatements in java.sql package to load multiple records. Moderately good performance interms of loading speed can be expected but once again not good enough for loading millions.

3 Using SQLLDR; end of story ;). All you need is to have a input file(which I'm sure you are having :)) then tell sqlldr which parts to in the file to load, which parts to ignore and is any transformation is needed for columns if any. Cant believe your ears ? It's that easy. In next section I'm going to discuss SQLLDR with more detail along with an example.

Friday, November 11, 2011

Diameter Protocol based Application Development

Diameter is one of the main interfacing protocols defined in the 3gpp standard. (For people who do not know what this is, 3GPP essentially defines the telecommunication architecture and its related standards.) Its uses include
  1. Online and Offline charging applications
  2. Online authentication

Diameter protocol uses a set of sub units called "AVP". Each AVP contains a specific type of information. This type of information can be anything from a simple login name to a much more complex charging attribute ( I will discuss them in a later post). Each AVP is identified by a numeric code.

3GPP standard has defined a set of standard AVPs. These AVPs include,

  1. Host Name AVP
  2. Destination Host AVP, etc.