Design Alternatives - Conclusion!

So what we have so far?

 

  1. We want software mechanism to embed error or fault injection to see how our module handles, at least, some of the basic stuff.
  2. It is not enough to say, after using API we check for error, and take the appropriate execution path. Instead, we must exercise the error handling paths by injecting some basic errors.
  3. As always, the code to inject errors has to be minimally invasive in the sense that the code can to production, but will never generate the code for error injection. While under test, we can inject those errors as required.
  4. Alternatively, use external error injections as an ad hoc fashion.

 

 

All the triggers are of the first type of error injection. It is inside the production code, just does not need to be compiled into the production binary. 

 

On the otherside of the fence, is to use separate module/infrastructure etc., to inject errors. For kernel programming in platforms where filter and/or stream drivers infrastructures are available, they are sometime good alternatives. For example, under windows, I've used filter drivers to inject errors on IRPs. For linux/unix, I worked on stream drivers that take the burden of injecting errors to main device drivers at will.

That's it for a basic error injection and design to debug!

 

Happy new year to all!

Posted on Monday, January 2, 2012 at 10:31AM by Registered CommenterProkash Sinha | CommentsPost a Comment | References1 Reference

Design Alternatives II

Continuing last note ...

What I found from my previous experiences that even if we format or simply add one char in a comment, and save source file, we should really go thru the whole process of building the software and run thru a series of test processes. This is bit strict, but for any production quality software we really should follow this process. 

On top of it, quality assurence process should not tuch the source and / or binary. They should mostly use as built software and do all sorts of error testing and analysis. There are variations of this approach, but mostly this reduces confusions among team members.

Most of the code we do for error conditions and possible actions are of IF-THEN-ELSE, and there are TRY-CATCH type patterns. One example is, for example, memory allocation. How do I make the system to force a failure in memory allocation API that was provided by the system library?

One approach is that we can wrap anysuch system calls in another functions and fail it there, but that requires extracode, and managing between Release and Debug build could be unnecessary work.

I use some simple macros in the code itself to make sure the error paths works. As an example, let's say I want to force an error on a memory allocation, I use the following pattern.

if (TRIGGER  ( (memVa = malloc(n) ) == NULL )  ){

HandleTheErrorPlease(...);

}else {

/* success */

DoTheProcessing (...);

}

 

This is just a simple example for triggering, and depending on what kinda triggering and at what point in time I want to trigger, I can inject error conditions at different code paths with different types of error.

 

Now what I get out of it?

 

1) Does it handle errors correctly?

2) No code changes, between production and test codes.

3) Total code coverage - to eliminate dead code.

 

Posted on Thursday, November 24, 2011 at 01:50PM by Registered CommenterProkash Sinha | CommentsPost a Comment | References2 References

Design Alternatives

It's been a while since I last posted here...

One thing I'm interested is to design for debugging. It means, that as and when we design some software, we want to make sure that debug code is still in the design. It should be placed carefully and turned on when needed.

You may ask, why? In fact, I was trying to implement error handling of all sorts in a large kernel module that is sitting in the middle of storage stack. And as we know, shoe-horning this kinda stuff is quite challenging. What it was for? It was to make sure (1) user data don't get lost or corrupted (2) Seamless recovery. 

 In my rookie days, I worked with very shallow level of fault tolerence in network stack - the idea was to modulerize the component(s), and roll-back ( meaning re-init) progressively based on watchdog response. And we all know there is a fundamental problem with watchdog mechanism - refer to internet for some nice articles on it by Embedded System Design magazine.

So I ended up copying some crucial ( hot-path ) routines, give them new names, and let the software take those paths that are only for error handling, and then debug / change / whatever... This way I don't upset the normal paths of the code. This is sort of Bypass surgery!! Then when I found those Bugs, found the symtoms, just change the circuit of code flow.

The problem was that injecting errors in the main storage stack of any OS would upset the system in an unimaginable number of ways. In Windows, I saw so many bugchecks like: many different varieties of Hive Corruption ( Note that Win 7 onward, Hive mgmt in the OS is more robust, and still ...), no paging file, ntdll's breakpoint interrupt and others. It basically indicated that - time of the error ( what type of IRP had the error; number of errors; load of the system at the time of the error; type of the load ( random, or read only, or write only etc) and other thing would determine in an yet unpredictable way for the type of bug check and/or corruption of the system volume.

This why I think design to debug is what shine for good software. As an example, the code should be armed with trigger infrastructure. For the detail of the trigger infrastructure, I will have to take another note later.

Posted on Saturday, November 12, 2011 at 09:22AM by Registered CommenterProkash Sinha | Comments Off

Looking thru Windows - It's almost summer!

This winter is pretty interesting! Few Blizzards in the East Coast, and fairly good amount of rains in the West! Really I can't believe it is already end of May and it is cloudy/rainy here. By now, it should have been a season to look thru windows - blue sky, beautiful armoa of spring with bunch of pollen to clear my nasal passage!

Oops, it is not intended to talk 'bout those windows, actually it is about Windows. It's been a while that I could not get my hands around it, now getting back to hack.

For a while, may be 5 years or so my better half was saying, clean up those mess, they are old CDs, the books are obsolete, and why do you need to carry them around. I was just ready to put some of those in the recycling place, and now I need them. Actually quite badly to brush off  the dust from the books and from my head!

 About 20 years ago, it was really fun to solve some graph algorithmic problem, well it was due to lack of better things to do perhaps!. Now I see another branch of applications where I really need to understand the difference between RAM and PRAM programming model for having an estimate of the alogorithm performances. These were abstract concepts at that time, now they have real and practical significance.

For example, Memory Managment and storage stacks. We know that from the higher level a storage system is abstracted as an array of blocks of memory on the secondary storage. And for a long while, this has been one of the fundamental abstraction now due to different media technologies the implementation of this abstraction could be quite different, and guess what that requires some fundamental understanding of graph algorithms. 

To name a few: List ranking, B tree, B+ tree, Shortest Path, Eulerian Circuits etc...

Some of us know what they are, or even know where to look before implmenting it...

But I will later try to stress some of them by asking questions like: What, Where, How, and When and finally Why.

 

Posted on Thursday, May 26, 2011 at 07:25AM by Registered CommenterProkash Sinha | CommentsPost a Comment | References1 Reference

What knocks your socks off - You may ask.

My answer to this is pretty much everything does it to me! Well, not exactly. Specially when I have sound sleep, I don't think anything knocks my socks off during that time :).

 

If I asked my younger kid (who about to start High School) the following - You have 9 socks in a drawer. There are 3 black socks and 6 socks. What is the minimim number of socks you will pick up ( without looking at the colors) so that you get a pair of socks of same color. Not that he does not know the answer to it but being funny as they are (mainly because we were successful to inject the humor in their brain from early days of their lovely life ), he might respond like the following -

1) I will drop everything on the floor then pick two of the same color, what is the big deal Baba(i.e. Dad) ? And I will try to explain it is a little puzzle so without looking at them you have to come up with two socks of same color.

2) He might respond - Baba, who told you that I've have to have the same color to put on. Also how do you know that I need to wear exactly two of them. I might just be fine using one and the other could be without a sock or I even might say forget it, I will just put my shoes on without any socks.

And I would not ask this question to the elder boy, he might seriously laugh at me and could say - Baba, you are sick, so sick, sooooo sick and walk out without answering me. And I would be totally confused, he really really meant to say I'm sick or it is just brilliant question and he loves it. You know the kids talk, right? When they see something that excites them really - they say, it soooo sick Baba. I just love it, I'm a big fan of these puching of words, and I think that makes the langugage, conversation, and communications so sick :)

But this question is dedicated to my wife - It's mother's day, and she is solving math problems being a teacher by profession....

The answer is easy, if we draw 3, we will have a pair of same color.

Okay now you own 1 red sock, 2 indigo socks, 3 blue socks, 4 green socks, 5 yellow socks, 6 orange socks, and 7 violet socks.

It is not that difficult, but formalizing might require a bit of thinking! Well, this not the real problem I'm about to embark on, so it would be instructive to play around the little examples like the first one and change the parameters and see if you can find the patterns. So first find the parameter(s), then change them. Once you find the patterns there is an underlying mathematical concept lurking behind it that we often conciously or unconciously use when programming :).  

So you warmed up, right? Now the original problem that is the subject to this blog -

 

A drawer contains red socks and black socks. When two socks are drawn randomly, probaility that both socks are red is 1/2. (a) How small can the number of socks  in the drawer be? (b) How small the number of socks in the drawer be, if the number of black socks is even?

Well this is not going to be easy, and I will try to sketch the area of logic and math required to solve this. Once I knew all the areas involved in solving this type of problem, but solving few of them like this is the real challenge I think. So I will step thru some procedures that solves this, and it is definitely not my steps...  So next time I will illustrate the steps for solving this kind of problems, and it would be even more interesting to program the observations to see how it works!

 

Now back to the last blog's solution. Remember that we were given 1000 coins that are laid out as a line. The coins are in different dominations. Alice's objective to win by grabing more money than her opponent, well of course following the rule. If not then at least get even...

The problem has some structures (1) If Alice determines that picking just the odd numbered will give her the winning chance, then she could apply a process that force the opponent to pick even numbered coin. (2) Similarly it is true the Alice could win just my sticking to odd numbered (positioned) coins.

So Alice first run thru the coins and adds the values of odd positioned coins in one one sum, and do the same for even positioned. Now compare the two sums. If the odd positioned sum is greater than even positioned sum, pick the first odd positioned coined that happens to be at the start. 

Rest does not need any explanation!

 

Finally I would take the liberty to recommend two books -

1) Choice and chance by W.A. Whitworth

2) Algorithms and Programming Problems by Alexander Shen.

Posted on Sunday, May 8, 2011 at 11:20AM by Registered CommenterProkash Sinha | CommentsPost a Comment | References2 References