Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Thursday, March 24, 2011

Windows and Unix way of dynamic link library management

Dynamic/Shared libraries: Differences Between Unix and Windows
[ On Unix, linking with a library creates a separate copy of it, But Windows will not create a copy. Its keeps a reference to the functions inside the libraries]


Unix and Windows use completely different paradigms for run-time loading of code. Before you try to build a module that can be dynamically loaded, be aware of how your system works.

In Unix, a shared object (.so) file contains code to be used by the program, and also the names of functions and data that it expects to find in the program. When the file is joined to the program, all references to those functions and data in the file's code are changed to point to the actual locations in the program where the functions and data are placed in memory. This is basically a link operation.

In Windows, a dynamic-link library (.dll) file has no dangling references. Instead, an access to functions or data goes through a lookup table. So the DLL code does not have to be fixed up at runtime to refer to the program's memory; instead, the code already uses the DLL's lookup table, and the lookup table is modified at runtime to point to the functions and data.

In Unix, there is only one type of library file (.a) which contains code from several object files (.o). During the link step to create a shared object file (.so), the linker may find that it doesn't know where an identifier is defined. The linker will look for it in the object files in the libraries; if it finds it, it will include all the code from that object file.

In Windows, there are two types of library, a static library and an import library (both called .lib). A static library is like a Unix .a file; it contains code to be included as necessary. An import library is basically used only to reassure the linker that a certain identifier is legal, and will be present in the program when the DLL is loaded. So the linker uses the information from the import library to build the lookup table for using identifiers that are not included in the DLL. When an application or a DLL is linked, an import library may be generated, which will need to be used for all future DLLs that depend on the symbols in the application or DLL.

Suppose you are building two dynamic-load modules, B and C, which should share another block of code A. On Unix, you would not pass A.a to the linker for B.so and C.so; that would cause it to be included twice, so that B and C would each have their own copy. In Windows, building A.dll will also build A.lib. You do pass A.lib to the linker for B and C. A.lib does not contain code; it just contains information which will be used at runtime to access A's code.

In Windows, using an import library is sort of like using "import spam"; it gives you access to spam's names, but does not create a separate copy. On Unix, linking with a library is more like "from spam import *"; it does create a separate copy.

Wednesday, April 21, 2010

Memory leak management while using apache libraries



   I had faced a memory leak  issue when using apache APIs to create sockets. My application designs to monitor some set of ports continuously in a frequent time span. Application internally uses APIs from apache library to create memory pool, to create sockets, to shutdown socket etc..
First, it will create a pool of memory by using apr_pool_create function as below .
apr_pool_create(&newPool, NULL)

And then it makes a socket address with apr_sockaddr_info_get call as below.
//making socket address
apr_sockaddr_info_get(&remote_sa, dest, APR_UNSPEC,
(apr_uint16_t)portNum, 0, pool)

Then it creates a Socket as below.
apr_socket_create(&sock, remote_sa->family,
SOCK_STREAM, pool))
After creating socket, it tries binds to the port.
apr_bind(sock, remote_sa)
Then connect to the port and started listening for a connection request.
apr_connect(sock, remote_sa)

And then below functions are used for other usual socket activities.
apr_sleep(10000000);
apr_recv(sock, dataRecv, &length);

After the socket's tasks finished, we used to shutdown the socket and close for further actions.
apr_shutdown(sock, APR_SHUTDOWN_WRITE)
apr_socket_close(sock)

These all above code works in a while(1) loop. Creation of memory pool is a one time activity. Remaining tasks(from socket creation to socket closing) are continuously looped until application killed.
This application will be working as a process, which always present in active memory to listen the specified ports. I have received an issue from one of our customer saying that, he is observing a memory leak while running this process. I took this task and me too observed the same issue in my development server.
In general, reproducing a problem is the 60% of the solution. But, in memory leak problem, it will be only 40%. You may observe a leak, but you may not come to a conclusion that, this leak is happened by this reason.
I did a regular memory leak check up in the big code base. I searched from malloc, realloc, calloc etc. And I searched for any macros defined against malloc.

Nothing!!! No memory allocation calls used in the code. Then my spy glass went the the pool creation API (apr_pool_create). I observed that Memory pool is created but not freed any where. I have Apache API to delete the pool. But, if I delete the pool, application will be killed immediately. I wanted to retain my application in active memory unless, user forcefully killed him.

So I cant use apr_pool_destroy to release the memory pool. Then i visited Apache Portability Runtime library for the API reference . I found there is another call apr_pool_clear(pool) to clear the memory location. GOD GRACE. I did that !!!.
My issue is resolved. So whenever a new socket finished his tasks, he will clear the pool and return the handler to begin. And then new socket will allocate the memory from free pool. Hence no memory leak !!!