Gary
Gary

Reputation: 243

Bizarre memory issue?

I'm having an interesting problem, which I hope is entirely my fault.

I have code which is reading from a queue, as in:

 do {
    evt       = &newevts[ evt_head++ ];
    evt_head &=  MAX_EVENTS;

    if (evt->index <= 0 || evt->index > MAX_INDEX) {
         printf("RX EVENT BAD NDX: ndx=%d h=%d\n",evt->index, evt_head);
         continue;
    }

    //... etc ...

 } while(evt_head != evt_tail) ;

The bizarre issue is the if statement can evaluate to evt->index being a bad value, but when the printf displays it shows a perfectly valid value! Example:

RX EVENT BAD NDX: ndx=1 h=64

The if statement clearly shows the condition must be <= 0 OR > 1024 (max index). To make matters worse, this only occurs once in a while. I'm using GCC, Centos 6.3. No threads touch evt_head except this thread. (I've renamed it a few times and re-compiled just to be sure.)

The tail is handled by a function which adds items to the queue in the same manner the head removes them (increment then AND). I have also added a counter inside the event structure itself to record the head/tail values as events are placed into the queue and find no lost or skipped values. It literally looks as though I'm getting some bad memory reads. But that's ridiculous - I'd expect system crashes or at least program crashes if that was the case.

Any ideas on how in the world this could be happening sporadically? (Frequency is about 1 out of 100 reads) I appreciate any input!

typedef struct {
    int    index;
    int    event;
} EVENT;

#define  MAX_EVENTS  0x01ff
#define  MAX_INDEX   1024

No threads or other code touches evt_head. Only this loop. The queue is never anywhere near full. I also happen to have a "SPIN LOCK" on entry to the routine which adds to the queue (in preparation for it being other-thread-accessed later), and an UNLOCK on exit.

Upvotes: 4

Views: 140

Answers (1)

s.bandara
s.bandara

Reputation: 5664

My guess is that the function adding events to your tail will change evt_tail before writing the index field. This allows your reader to access an event that is still in the process of being written.

Upvotes: 2

Related Questions