Friday 10 February 2012

Start tracking a bug and you can see more waiting for their turn to ruin your software....

It so happened with me that I was tracking my important speed post and I found it delivered to a wrong address by my area postman.Imagine what worse could happen.He cannot track the person to whom he has delivered it. A big bug in postal service.

This post had a link with my bank account. When I went to update this post's missing information in bank, I got to know that my file/credentials are migrated to different branch, without any notification to me. A bigger bug in bank service.

Why don't they hire an experienced IT guy, who will review their workflow and check all exceptions handled?

Anyway, let me tell you what I saw in a code base the other day I was tracking a bug. A knowledgeable but lazy developer calls a function and doesnot extern the function prototype; biased by an idea that the compiler and linker should bear this load (as they really do).For most of the people, who keep extern keyword blinking in their mind, in series with linker, I would say, compiler also has to mark the externed symbol as unresolved while creating the symbol table in a .O file.

He called a function to allocate memory on heap passing unsigned 64 bit datatype(unsigned long long int). The function has the formal parameter as unsigned int. Something like this:
processMessageA(........, ......, ......, length);
where
processMessageA(....., ......, ......., u64 len)
{
       --------------
       ---------------
       memAlloc(......, 2*len);
       ---------------
}

The developer also assumed that the  2*len will be implicitly truncated to unsigned int while passing argument to memAlloc.Since the extern declaration of  memAlloc was missing, ARM compiler assumed the formal parameter of memAlloc to be same as that of the size of actual argument passed i.e. 8 bytes. In caller (processMessageA)context,  it picks the length value(8 bytes) from stack frame of processMessageA multiplied it with two and passed it as argument to memAlloc without truncating to unsigned int.

As per Arm Thumb Procedure Call, this 8 bytes size argument was passed in two registers to the memAlloc function. However , the implementation of  memAlloc expected size in one register and some other data in the other register. As a result, the program crashed while executing memAlloc.

While browsing through the source code, I saw a function call which resembled the call mentioned below:-
getMessageRef(poolId)->Body = data;

I found one case  when getMessageRef returned NULL, which if occured will cause a DATA ABORT on ARM(and SEGMENT VIOLATION on gnu/Linux). A hidden bug waiting its turn.

I donot feel any harm in making call to getMessageRef seperately like this:-
 if((pMessage = getMessageRef(poolId)) != NULL)
{
     pMessage->Body = data;
}

On same line, I feel, it is NOT safe and good practice to call functions in following ways :-
  • setEmployeeAge(getEmployeeId(COMPANY_A,pName),35) : A function call in argument list of another function.
  • getTaxPlanner(COMPANY_A, employeeB_id)(FN_YEAR_2012) : Two function call hidden in same line of code.
AAh, Finally I am out to publish this particular blog which was under draft since last 2 weeks. An IT guy working in India can surely understand what a weekend mean to him :) .

 

No comments:

Post a Comment

Note: only a member of this blog may post a comment.