Functions with variable number of arguments

In C/C++, functions can be written to take variable no. of arguments. Examples are printf, sprintf, snprintf etc. The prototype of printf functions looks like int printf(const char *format, …). These functions internally use macros such as va_start, va_arg, va_end etc to get the passed parameters. But, I have observed that for every function like printf, there is another similarly defined function which takes va_list instead of … . For example, vprintf is similar to printf and has int vprintf(const char *format, va_list ap) prototype. In the same way, vsprintf and vsnprintf are also defined. Till now, I did not know the reason and used to think of it as an unnecessary wrapper.

For example, if a wrapper called myprintf needs to be written over printf

int myprintf(const char* format, …){

va_list ap;

va_start(ap,format);

???????

va_end(ap);

}

In the above code, I can not put ‘printf’ in place of ??????. Because printf is expecting variable arguments (like i, j , l) and not va_list dataype. So, in place of ??????, I should call vprintf which takes va_list.

So, I observed that it is a good practice to write 2 functions in case of variable number of arguments. One which takes variable no. of arguments as … and the other one taking va_list. An example is given below.

void vfunction (char * format, va_list ap){

/*This function does the actual work*/

}

void function(char* format, …){

/*This function just redirects to vfunction which does the work */

va_list ap;

va_start(ap,format);

vfunction(format, ap);

va_end(ap);

}

New tricks that I have learned in using debuggers

In gdb/dbx, we can see the variable using addresses. Suppose a structure [struct Box * b] is not deallocated but we are setting it to NULL i.e. b = NULL. We can not access that structure using b. But if we know the address pointed by b [we can get it using print b], we can access it like *(struct Box *) (0x4f2b2448) [assuming 0x4f2b2448 is the address that b points]. Obviously this is a very simple thing. But, I have used it for the first time. Similarly, when setting watchpoints over variables like watch b->length, if the control goes to some other place where this variable b is not in scope, that watchpoint will be deleted. [Atleast this happens in old gdb versions, I’m using SuSE 8]. So, in those cases you can put watch point over address so that it is accessible from anywhere. watch ((struct Box *)(0x4f2b2448))->length works fine.

nm & dump in AIX

In Solaris, Linux and HP-UX, I have used nm to see exported symbols in my shared library. So I have started using the same command in AIX also. But, in the command output, all my exported symbols are prefixed with dot [.]. Moreover, there are lot many symbols in ” T ” [Global Text] section of the output. Even, basic string functions like strlen, memcpy are also under ” T “. I thought there might be a bug in my makefiles and tried to fix them. After debugging this for 6 hours, I thought of trying other commands also. Finally I have tried dump [dump -HTv] and I got the output exactly what I have expected. Functions like strlen,memcpy are under undef section. So, in AIX, it is better to use dump for seeing symbols in the shared library. As I dont have free time, I have not investigated why nm was showing symbols in a different manner.

Useful non-crypto modules in OpenSSL crypto library

In C/C++, for secure networking/cryptography, I feel OpenSSL is the best choice. Other than cryptography/secure networking, there are many other good modules in OpenSSL that can be used in various applications. Few of them are BIO, BN, ASN1. BIO is an abstraction layer over I/O. By using BIO, we can do Socket I/O, File I/O, in-memory I/O etc. Moreover, BIO can be used as a filter also; ex: we write plain text to BIO, we get the encrypted text when reading from BIO. BN is a BIGNUM library. It is a library for handling very big numbers. For creating very big primes, arithemetic operations on very big numbers, we can use BN module. ASN1 is the abstract syntax notation module. Using this module, we can use many ASN1 functions. As I know, these 3 are very good non-crypto modules. If you consider cryptography or ssl, OpenSSL has everything. Moreover, it comes with a very flexible license.

Gmake going in loops??

From many days, I have observed that our build sometimes goes into recursive loops and does not get out of the loop for many hours/days. I found the reason for this problem. It is about the modification time of makefile & C/C++ files. I use tar.gz which preserve file modification times and transfer that tar.gz to other systems. If those systems have different timezone, it might happen that the makefile/c/c++ files are modified in the future. Since gmake considers file modification times when running makefile, it goes in recursive loop. Simple solution is to touch the makefile/c/c++ files with future modification time using touch command.

Solaris:Make a shared library which can be executable

After many days, I got some free time to continue the work that I have done here.
In solaris, I know, by writing asm code, we can make a shared library work as an executable. So, I thought of writing a simple tool which can make necessary changes to shared library to act as an executable. First I have read cc man page to find out how to set an entry point. I found that we have to pass -e option to linker. So, I have written a test program [download] and compiled it to create a shared library. When executed it [$./libtest.so] , it gave segmentation fault and failed. It was setting entry point correctly. I have used elfdump to check whether it is setting entry point properly or not. We can see entry point with elfdump -p <executable> [e_entry value]. We can search for that entry point in ‘elfdump -s <executable> | grep <e_entry value>’. For reading the section headers, I have used the example given in elf man page. Then, I have executed that section header print program on that shared library. Then I have observed that the created shared library was not having ‘.interp’ section. ‘.interp’ contains interpreter value. After loading the file, system handles the control to interpreter, if ‘.interp’ section exists. So, at this stage, I thought of writing a program using elf/gelf library to add the interp section. But, when I read the man pages again, I saw -I option to linker to set the interp value. [By default, for executables, .interp section is created and /usr/lib/ld.so value is set. By default, For shared libraries, it wont create any interp section]. So, I have used -I option to compile my program into library. Now, entry point is correct and .interp section is also there. When executed my shared library [$./libtest.so], it executed normally without giving segmentation fault.

One more problem here is to get the command line arguments. I think, we have to write some assembly code to do that. If you want that feature, you can refer to this and this. you can download my programs here.

Do we need __PRETTY_FUNCTION__ like macros in other compilers?

You might know that GCC in addition to __func__ macro, it supports __FUNCTION__ and __PRETTY_FUNCTION__. __func__ is the predefined-macro which contains the function name in a string. It is defined in C specs, But, __FUNCTION__ and __PRETY_FUNCTION__ are extensions by GCC. __FUNCTION__ macro is same as __func__. __PRETTY_FUNCTION__ macro gives the full function declaration including parameters and return values. I tried to look for other alternatives on SUNWspro compilers and HP-C/C++ but could not find any. Then I questioned myself ‘do we need this macro while we can always get sufficient debug information with __LINE__ , __FILE__, __func__??’.  Answer is ‘No’. We can always get sufficient debug information with the macros defined in specs. More over, if we use GCC extensions in code, portability to other platforms is a big pain. BTW, VS.net compiler also has a similar pre-defined macro for getting decorated function name.

Seeing pre-processor macros in gdb

In gdb, we can see the source code while debugging. But, if there is any macro in the source code which is defined in some other file, then we have to search for that macro outside gdb [using fgrep] and see what it expands to. In complex codes like openssl, it is even difficult to find/understand macros. When I was searching for this kind of feature in gdb, I saw this link. Then, I came to know that this feature is already implemented. After further research on this topic, I read this link. In this link, it says, if we build our source code with -g3 -gdwarf-2 , it will include all the macros in the debug information. So, I have written a test program and built it with those options. After that, in gdb, I have tried $info macro <Macro.Name>, it gave the line no# where the macro is defined and full macro definition. In addition to just seeing macros, we can use ‘macro expand’ command to see what the macro expands to.

One interesting note: I tested a small program and it worked in my SuSE8.1, GCC3.2.2, GDB5.3. I have tried to test the same thing in Fedora-core3, GCC3.4.2, GDB6.1, it did not work. I think it is the problem with GDB [though I am not sure]. GDB needs to support these debugging formats. So, if we build GDB with proper flags, I think it will work.

I read that there are better debug formats than dwarf-2, one among them is stabs. But, once again, your debugger needs to support it.

Stack traces in C/C++ programs in solaris & linux

In Java, there are direct APIs for getting stack traces. But, for C, there are no popular APIs for doing the same. So, I was just searching for this feature in linux. Then I came across this link. It provides very clean and simple interface for getting stack traces. They even gave the sample program in the end of the article, demonstrating how to use it. Note: We have to compile the program with -rdynamic flag. In solaris, I know, with dtrace tool, we can do all these tricks. But, if I want to get/use the stack trace inside the C program, dtrace doesn’t help. After searching for “stack” in /usr/include/*.h contents, I found some functions in ucontext.h, which are relevant to what I want. Then, after seeing man page of one of their functions [man printstack], it is confirmed. I have written a small program to demonstrate stack traces in C program. You can download it here. For C++ programs, we may have to use c++filt [like ./a.out | c++filt] to get the correct functions names from mangled ones.

Finding memory leaks in solaris

I have started searching for a tool like memusage library in solaris. Then, I read about umem library. I felt, this tool is useful for finding memory leaks for a running program. We have to use the umem with mdb whose interface is very difficult to use. Then, after further exploration on this topic, I have opened sunstudio gui and started debugging with ‘memory checks’ on. Then, I found out that sunstudio is internally using dbx. So, I have noted dbx commands that are used for memory leaks.

dbx is more like gdb. first, we have to build the executable [CC test.c]. then start that executable using dbx [dbx ./a.out]. set ‘memory checks option on’ [check -memuse]. run the executable [run]. If there are leaks in our application, we will get a table like the following

Total Size Num of Leaked Blocks Block Address Allocation call stack
========== ====== =========== ====================
8 1 0x80688a8 func2 < func1 < func < main

This table is saying that, it has got a memory leak of 8 bytes in main>func>func1>func2 function. From this, we can know that memory allocated in function func2 is not freed. Now, we can guess where that allocated memory can be freed.

Enjoy! Happy leak free code!!

« Older entries