Prabakaran Blogs

How to detect memory leaks and memory corruption

Valgrind will save you hours of debugging time spent on analysing memory corruption. With valgrind tools you can detect many memory management and threading bugs. This gives you a feel that your programs are free of many common bugs. You can find and eliminate bugs before they become a problem with valgrind. Valgrind is a debugging tool for large, complex programs.

When to use valgrind?

  • For small programs with short run-times, when developing you can always run the program under a valgrind tool (usually Memcheck), knowing that memory bugs will be found immediately.
  • In automatic testing. By using Valgrind tools in your automatic unit, integration, system you can be confident no code will be unchecked.
  • After big changes. To ensure new bugs haven’t been introduced in the new code.
  • When a bug occurs. Get instant feedback about t the bug , where it occurred, and why.

Examples:

Ex. //test.c

int main()
{
char *p=malloc(100);
}

$gcc -c val.c

$gcc -osingo val.o

$ valgrind –tool=memcheck ./singo

output:

==16405== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 12 from 1)

==16405== malloc/free: in use at exit: 100 bytes in 1 blocks.

==16405== malloc/free: 1 allocs, 0 frees, 100 bytes allocated.

==16405== For counts of detected errors, rerun with: -v

==16405== searching for pointers to 1 not-freed blocks.

If you have a memory leak, then the number of allocs and the number of frees will differ . If the number of allocs differs from the number of frees, you can rerun your program again with the leak-check option. This will show you all of the calls to malloc/new/etc that don’t have a matching free.
Compile your program with -g to include debugging information so that Memcheck’s error messages include exact line numbers.

$gcc -g -o val1 val1.c

$valgrind –tool=memcheck –leak-check=yes .val1

output:

==19466== malloc/free: in use at exit: 100 bytes in 1 blocks.

==19466== malloc/free: 1 allocs, 0 frees, 100 bytes allocated.

==19466== For counts of detected errors, rerun with: -v

==19466== searching for pointers to 1 not-freed blocks.

==19466== checked 47,596 bytes.

==19466==

==19466== LEAK SUMMARY:

==19466== definitely lost: 0 bytes in 0 blocks.

==19466== possibly lost: 0 bytes in 0 blocks.

==19466== still reachable: 100 bytes in 1 blocks.

==19466== suppressed: 0 bytes in 0 blocks.

==19466== Reachable blocks (those to which a pointer was found) are not shown.

==19466== To see them, rerun with: –leak-check=full –show-reachable=yes

Reading/writing off the end of malloc’d blocks

Valgrind can also find the use of invalid heap memory using the memcheck tool. For instance, if you allocate an array with malloc or new and then try to access a location past the end of the array:

Ex. //val.c

main()

{

char *p=malloc(100);

p[120]=’b';

}

output:

==19489== Invalid write of size 1

==19489== at 0x80483EA: main (val1.c:6)

==19489== Address 0x40260A0 is not stack’d, malloc’d or (recently) free’d

Reading/writing memory after it has been free’d :

main()

{

char *p=malloc(100);

free(p);

p[23]=’b';

}

output:

==2808== Invalid write of size 1

==2808== at 0x80483EA: main (val1.c:6)

==2808== Address 0x40270a0 is not stack’d, malloc’d or (recently) free’d

Use of uninitialized memory:

main()

{

int x;

x++;

printf(“%d”,x);

}

output:

==3276== Use of uninitialised value of size 4

==3276== at 0x3A27DB: _itoa_word (in /lib/libc-2.7.so)

==3276== by 0x3A673F: vfprintf (in /lib/libc-2.7.so)

==3276== by 0x3AC9B2: printf (in /lib/libc-2.7.so)

==3276== by 0x80483EB: main (in /home/lakshya/rima/a.out)

Reading/writing inappropriate areas on the stack

main()

{

int s;

int *p=&s;

p[-2]=7;

s=p[-20];

}

output:

==3313== Invalid read of size 4

==3313== at 0x80483BD: main (in /home/lakshya/rima/a.out)

==3313== Address 0xbeb5e5bc is just below the stack ptr. To suppress, use: –workaround-gcc296-bugs=yes

Overlapping src and dst pointers in memcpy() and related functions:

 

ex:

main()

{

char buf[1000];

char *ptr1=&buf[0];

char *ptr2=&buf[400];

memcpy(ptr1,ptr2,500); 

}

output:

==3362== Source and destination overlap in memcpy(0xBE9ED224, 0xBE9ED3B4, 500)

==3362== at 0x4007CB2: memcpy (mc_replace_strmem.c:402)

==3362== by 0x804840B: main (in /home/lakshya/rima/a.out)

Passing unaddressable bytes to a system call:

Ex:

main()

{

char *ptr=(char *)malloc(100);

read(0,ptr,500);

write(1,ptr,500);

}

output:

==3382== Syscall param read(buf) points to unaddressable byte(s)

==3382== at 0x42B343: __read_nocancel (in /lib/libc-2.7.so)

==3382== by 0x37D38F: (below main) (in /lib/libc-2.7.so)

==3382== Address 0x402708c is 0 bytes after a block of size 100 alloc’d

==3382== at 0x4005AC8: malloc (vg_replace_malloc.c:207)

==3382== by 0×8048440: main (in /home/lakshya/rima/a.out)

 

==3382== Syscall param write(buf) points to uninitialised byte(s)

==3382== at 0x42B3C3: __write_nocancel (in /lib/libc-2.7.so)

==3382== by 0x37D38F: (below main) (in /lib/libc-2.7.so)

==3382== Address 0×4027033 is 11 bytes inside a block of size 100 alloc’d

==3382== at 0x4005AC8: malloc (vg_replace_malloc.c:207)

==3382== by 0×8048440: main (in /home/lakshya/rima/a.out)

 

Mismatched use of malloc/new/new [] vs free/delete/delete []

#include “stdlib.h”

main()

{

int *ptr=new int;

free(ptr);

}

output:

==3426== Mismatched free() / delete / delete []

==3426== at 0x400566C: free (vg_replace_malloc.c:323)

==3426== by 0x80484EE: main (in /home/lakshya/rima/a.out)

==3426== Address 0×4028028 is 0 bytes inside a block of size 4 alloc’d

January 2, 2011 Posted by | system programming, Uncategorized | , | Leave a Comment

Pointer Swizzling Technique

When we send structures containing pointers, data copy is involved to flatten the structure into contiguous buffer at the sender side and another copy is involved at the receiver side.

We can avoid one data copy at the receiver side using pointer swizzling

pointer swizzling

The contigous buffer should include space for the pointer member also during the marshall process as shown above. For the request structure, contigous buffer size would be

Sizeof(int) + sizeof(void*) + strlen(“Sample String”);

As the pointer value sent over the socket would not make any sense at the reciver end, it is sent with the buffer. At the receiver end, after receiving the  buffer, it would not copy the data to structure by creating a new object. Instead it would recalculate the pointer member and typecast the buffer to (struct Request*) and use it directly. It is illustrated in the below code snippet.

Sender Side
The below code snippet marshals the Request structure as per the pointer swizzling requirement. It copies the actual structure value at the beginning of the buffer and the actual values pointed by pointer after that.

Marshalling code:

   char buf[512];

   char *ptr = buf;

   memcpy(ptr, &request, sizeof(request)); //copy the struct at the beginning of the buffer

   ptr = ptr + sizeof(request);//copy the string value after the structure value

   strcpy(ptr, request.sVal);

   ret = write(sock, &buf, sizeof(buf));

   if(ret == -1){

      printf(“unable to send the request\n”);

      return 1;

   }

Receiver Side
The below code snippet unmarshals the Request structure. It resets the pointer value and sets it correctly to the actual value.

Unmarshalling Code:

      char buf[512];

      ret = read(new_sock, &buf, sizeof(buf));

      if(ret == -1){

          printf(“unable to receive the request\n”);

          return 1;

      }

      char *ptr = buf+ sizeof(int);

      //swizzle the pointer to the actual value(after the structure value in buffer)

      *(void**)ptr = buf + sizeof(struct Request);

      struct Request *request = (struct Request*) buf;

      printf(“Request got: %d %s\n”, request->iVal, request->sVal);

December 25, 2010 Posted by | Uncategorized | Leave a Comment

Swadeshi in IT industry

India, developer nation of the world provides IT services to other parts of the world by using the technologies developed by other countries. We have reached great position in IT as solution providers. All IT majors in India are into these services business by virtue of having many english speaking technology users like us. India produces Computer science engineers but all the engineers are working in IT services (solution providers) rather than creating products which enable solution providers to provide solution for the problems in other industry sectors.

Let’s take telecommunication sector, which provides mobile service to citizens of India. It depends on IT sector to set up the required infrastructure to provide service to its customer. They have to set up thousands of servers, networks, OS, SAN, Database server, Web servers, Billing servers, SMS Server, Speech recognizers, IVR platforms, Text to speech engines, Home Location Servers, Visitor Location Servers, VOIP servers, contact centre software, CRM, Auto Dialers,… and the list goes on.

 

Below is the set of product lines and companies who create them

Hardware (Desktop, Laptop, Servers) – Sun, Dell, IBM, HP

Network – Cisco, Nortel, Juniper

OS – Microsoft, Sun, IBM, Apple

Database – Oracle, IBM, Microsoft

Storage Area Network – IBM, HP, NetApp

Web Servers – IBM, BEA web logic

Billing Servers – Lucent, UTStar

Speech – Nuance, Telisma, Lumenvox

Contact center – Avaya, Genesys, Cisco

HLR/VLR/VOIP – Lucent, UTStar

CRM – Amdocs, Peoplesoft, Siebel

 

Though we are the biggest IT developer nation, our companies are still not there in the above list. Anyone out there in India who creates OS, Routers, Firewalls, Database engines, etc.

We are busy in providing solutions with products developed by the above mentioned companies. Computer science professionals are working on these technologies as users of these technologies rather than creating new technology.

We have lot of engineers who do system administration for OS, but none who creates better OS.

We have lot of engineers who do network administration for OS, but none who creates better routers and firewalls.

 

There are lots of private certification courses for administrators, but not even one on developing new products. This mandates huge effort from our side to make us ready for creating new products.

After getting into job, we are put in one domain (insurance) as programmer to develop some application using Java. After one year we switch from insurance domain to telecom domain because new employer will give 20% hike in salary. But what we do not understand is we lost one year of experience and we are not going to sharpen our knowledge on that domain anymore as we will have time only to struggle and understand telecom domain.

We move from domain to domain, and after some years we enter into middle management roles such as Team lead … and then project lead … and then project manager. By that time we are completely out of the technology and we become heavy desktop users by using word, excel, project plan, etc.

If this pattern continues, we will not be able to enter into product segment ever. I came out of this and decided my career based on my passion. I founded main memory database product named CSQL which boosts application performance 20 times faster for leading database systems like Oracle, Mysql, etc.

Join the product development wagon and be part of the revolution.

My Company

http://www.lakshyasolutions.com

CSQL Product Site

http://www.csqlcache.com

October 2, 2008 Posted by | IT, Uncategorized | , | 4 Comments

   

Follow

Get every new post delivered to your Inbox.