NXC: CurrentTick() bug, wrong NBC temp variable type

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
Post Reply
spillerrec
Posts: 358
Joined: 01 Oct 2010, 06:37
Location: Denmark
Contact:

NXC: CurrentTick() bug, wrong NBC temp variable type

Post by spillerrec »

I was trying my NXT RPG code again which I haven't touched for a half year (but with a new compiler and firmware). It compiled and ran, but when entering a specific part it froze.

Found the bug while writing this post, the spoiler is the text I wrote up to that point:
I found the reason, it was this piece of code:

Code: Select all

//Timing
while(t0+level_t1.D2DMargs.frame_time > CurrentTick()){
	Wait(10);
}
Initally it helped replacing level_t1.D2DMargs.frame_time with 150 which it was supposed to hold. However this also worked:

Code: Select all

//Timing
while(t0+level_t1.D2DMargs.frame_time > CurrentTick()){
	//ClearScreen();
	NumOut(0, LCD_LINE1, t0);
	NumOut(0, LCD_LINE2, level_t1.D2DMargs.frame_time);
	NumOut(0, LCD_LINE3, t0+level_t1.D2DMargs.frame_time);
	Wait(10);
}
Err, this shouldn't really have made any difference...

Well, even more strange was this:

Code: Select all

unsigned long t1=CurrentTick();

Input_Reset(); //TODO: make this work again somehow...

Draw_Level(Direction_Moved);//Draw map normally
unsigned long t2=CurrentTick();

//React on automatic events
Events_Handling(p1.pos_x, p1.pos_y, true);
unsigned long t3=CurrentTick();

//Display time used (and other debug values)
NumOut(0,LCD_LINE1, CurrentTick()-t0);
NumOut(0,LCD_LINE2, t1-t0);
NumOut(0,LCD_LINE3, t0);
NumOut(0,LCD_LINE4, t1);
NumOut(0,LCD_LINE5, t2);
The interesting part is the variable t1 (and t2). It is given a value from CurrentTick(). Then a few function calls happen that can't affect it since it is a local variable. It is used in two calculations which shouldn't affect the value and then displayed on the screen. And the value was 1... Actually it corresponded to the variable "p1.direction" or "input.dpad" (or some other variable that might be linked to these). So when I was pressing the move buttons and changed direction of the player, t1 (and also t2) changed correspondingly...
Just found the issue and it looks strangely familiar...
The compiled NBC code:

Code: Select all

mov __DU0Level_Type_1, input.dpad

...

gettick __D0Level_Type_1
mov __Level_Type_1_7qG2_t1_7qG2_001, __DU0Level_Type_1
gettick stores it in the temp signed variable, but the temp unsigned variable is used to retrieve the value. And the last time it had been used was with input.dpad... (I didn't notice they where different variables at first, thank God for Notepad++ highlighting identical identifiers, otherwise I would never have noticed...)
I know there was a similar case which was fixed, but I'm using the compiler from test_release20101103.zip. Anything newer than that?

I tried changing it to signed long, but the issues persist, it still tries to use a unsigned temp variable...
My blog: http://spillerrec.dk/category/lego/
RICcreator, an alternative to nxtRICeditV2: http://riccreator.sourceforge.net/
muntoo
Posts: 834
Joined: 01 Oct 2010, 02:54
Location: Your Worst Nightmare
Contact:

Re: NXC: CurrentTick() bug, wrong NBC temp variable type

Post by muntoo »

spillerrec wrote:thank God for Notepad++ highlighting identical identifiers
So you think Don_Ho == God???

Also, could you post a larger* sample of the NBC code? Those few lines aren't enough for a NBC newbie like me. :)

*By that, I mean like 20 lines of code max.
Image

Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE


Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: NXC: CurrentTick() bug, wrong NBC temp variable type

Post by afanofosc »

I need a small program that demonstrates this bug. I don't see it at all here:

Code: Select all

task main()
{
  unsigned long t1 = CurrentTick();
  
  NumOut(0, LCD_LINE1, t1);
}
With level 1 optimization:

Code: Select all

	gettick __D0main
	mov __main_7qG2_t1_7qG2_000, __D0main
With level 2 optimization:

Code: Select all

	gettick __main_7qG2_t1_7qG2_000
John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
muntoo
Posts: 834
Joined: 01 Oct 2010, 02:54
Location: Your Worst Nightmare
Contact:

Re: NXC: CurrentTick() bug, wrong NBC temp variable type

Post by muntoo »

afanofosc wrote:I need a small program that demonstrates this bug.
Unfortunately, this kind of behaviour seems to happen to me only in large programs. Trying to shrink it down is hard... (for me).
Image

Commit to LEGO Mindstorms Robotics Stack Exchange:
bit.ly/MindstormsSE


Commit to LEGO Stack Exchange: bit.ly/Area51LEGOcommit
spillerrec
Posts: 358
Joined: 01 Oct 2010, 06:37
Location: Denmark
Contact:

Re: NXC: CurrentTick() bug, wrong NBC temp variable type

Post by spillerrec »

I somehow managed to make a small program with the bug. It appears to be a function call that creates the issue.

Code: Select all

bool func1(){
	PlayTone( 2000, 1 );
	return true;
}

task main(){
	while( true ){
		ClearScreen();
		unsigned long time_0 = CurrentTick();
		NumOut(0, LCD_LINE1, time_0 );
		func1();
		unsigned long time_1 = CurrentTick();
		NumOut(0, LCD_LINE2, time_1 );
		Wait( 50 );
	}
}
time_0 works fine, however time_1 contains 1 which is func1()'s return value. The issue disappears if I change func1() to a void return type, however the original program used void functions.

muntoo, some NBC code for you: (of the example program)

Code: Select all

thread main
	subcall __initialize_global_data, ____initialize_global_data_return
__NXC_Label_562:
	set __D0main, 1
	tst 5, __zfmain, __D0main
	brtst 4, __NXC_Label_563, __zfmain
#pragma macro 6
	mov __PointOutArgs.Location.X, __constVal200
	mov __PointOutArgs.Location.Y, __constVal200
	mov __PointOutArgs.Options, __constVal1
	syscall 14, __PointOutArgs
	gettick __main_7qG2_time_0_7qG2_001
	set __signed_stack_001main, 0
	set __signed_stack_002main, 56
	mov __DU0main, __main_7qG2_time_0_7qG2_001
	mov __TextOutArgs.Location.X, __signed_stack_001main
	mov __TextOutArgs.Location.Y, __signed_stack_002main
	set __TextOutArgs.Options, 0
	numtostr __TextOutArgs.Text, __DU0main
	syscall 13, __TextOutArgs
	mov __D0main, __TextOutArgs.Result
	subcall func1, __func1_return
	mov __DU0main, __DU0func1
	gettick __D0main
	mov __main_7qG2_time_1_7qG2_001, __DU0main
	set __signed_stack_001main, 0
	set __signed_stack_002main, 48
	mov __DU0main, __main_7qG2_time_1_7qG2_001
	mov __TextOutArgs.Location.X, __signed_stack_001main
	mov __TextOutArgs.Location.Y, __signed_stack_002main
	set __TextOutArgs.Options, 0
	numtostr __TextOutArgs.Text, __DU0main
	syscall 13, __TextOutArgs
	wait 50
	jmp __NXC_Label_562
__NXC_Label_563:
	exit -1, -1
endt
My blog: http://spillerrec.dk/category/lego/
RICcreator, an alternative to nxtRICeditV2: http://riccreator.sourceforge.net/
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: NXC: CurrentTick() bug, wrong NBC temp variable type

Post by afanofosc »

It looks like this will fix the problem (and in the tests I have run so far does not seem to break anything):

Code: Select all

#define JCHCurrentTick() asm { gettick __URETVAL__ }
If you can try that out as an alternative to CurrentTick and let me know if you see any cases where it is getting confused about register types I would be grateful. The difference between the above and the definition of CurrentTick in NXCDefs.h is __URETVAL__ instead of __RETVAL__. The compiler replaces these tokens in ASM blocks with the signed or unsigned register variable name.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
spillerrec
Posts: 358
Joined: 01 Oct 2010, 06:37
Location: Denmark
Contact:

Re: NXC: CurrentTick() bug, wrong NBC temp variable type

Post by spillerrec »

I tried replacing all the CurrentTick() calls in my program including those which were working fine (10 in total) and everything seems to be working as it should. The animation is fluid and the timers returns the values I expect.
I will try it in some of my other programs later.
My blog: http://spillerrec.dk/category/lego/
RICcreator, an alternative to nxtRICeditV2: http://riccreator.sourceforge.net/
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest