Pointer argument in registers being passed on as NULL?

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Guys

I've encountered a problem with some code and I am trying to understand why it's happening.
First off we're usingn avr-gcc 4.1.1 for legacy reasons, on an ATMega 2560; incase that's pertinent

The code has various large structs passed around to different handlers normally with functions of the format:
- task_handler(Task*, callback, void* largeStruct);

normally this works fine but I have just encountered a case where I am trying to pass on the largeStruct pointer to another handler in the callback and by the time the handler is about to cache it it is NULL?
- looking at the debugger the pointer was in two registers

I can make it work if create a variable within the handler to store the pointer; this appears to make it hang around.

I am really confused as to what I am doing wrong?

The pseudo code below might help explain this:
- basically the BigObject* gets used correctly by the getResource callback
- but by the time that task_do gets called the value stored in Task->reference is NULL

Any ideas what I've done to make this happen?
As I said if I create a variable on the stack to hold the pointer and force it to hang about it works (getting passed in correctly)
All the best
sd

typedef struct {
	uint8 handlerState;
	uint8 buffer[128]
	uint16 etc;
} Task;

typedef void (*Completion)(void* userRef, uint8 err);

typedef struct{
	uint8 state;
	Task subTask;
	Completion callback;
	void *reference;
} BigObject;

BigObject obj;

void task_do(Task* thistask, Completion callback, void* reference){
	thistask->callback = callback;
	thistask->reference = reference; // <<-- this is NULL as registers are empty
}

static void _gotResource(void* reference, uint8 err) {
	BigObject* obj = (BigObject*) reference;

	_serviceBigObject(obj, err);
}

static void _serviceBigObject(BigObject* obj, uint8 err){

	if (err){
		return err;
	}
	switch(obj->state){
		case 1:
			get_resources(&GlobalResourceController, _gotResource, (void*)obj);
			break;
		case 2:
			task_do(&obj->subTask, _serviceBigObject, (void*)obj);
			break;
		default:
		break;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Haven't got time for a thorough study, but see if you can rewrite the code so as not to use void pointers and casting operations. Unless there's more to your problem than you've shown, all of your interfaces should be declarable in terms of pointers or references to your various defined structures. Maybe somewhere along the road to making a cleanly compiling version of your code after removing all the error-and-warning-disabling casts, an insight will emerge.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can you show the lss. Clearly no one here is likely to have a copy of 4.1 so we cannot build your test case so only study of the generated assembler might help to identify the issue. If it is a compiler bug (likely in something so old) then would this not be an apposite moment to consider an upgrade of compiler? The 4.6.2 Atmel currently have appears very stable. They also have a 4.7.2 in AS6.1 Beta but that's perhaps more of a risk at this stage.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Generally speaking, for such "phenomena" I believe that in almost all cases they are due to coding errors rather than compiler bugs.

Especially when casting things to void pointers and then later casting them back to something more specific.

Look for buffer overwrites, casting pointers back to types "larger than what the object actually is" (and thus, when accessing members in it you overwrite something else), etc..

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Apologies Guys for taking so long to thank you for the replies
- I had written a post earlier but must have neglected to submit
- basically I had indeed destroyed some data (via a bad dereference somewhere down the stack)
Thanks again for the pointers.
All the best,
sd