Help - Random function not working

@timmahh...Thank you for posting the code and the disassembler source. The code is fairly easy to trace as the AVR only has 136 instructions but still is quite tedious. Could you tell me the sources for both code segments, the difference is quite significant.

Sources == Source Code?

If so... both should be the very same.. I noticed the large difference as well..

long randNumber;

void setup(){
  Serial.begin(9600);
  randomSeed(analogRead(0));
}

void loop(){
  randNumber = random(300);
  Serial.println(randNumber);

  delay(50);
}

timmaah, this is great, but I made a mistake. We can get a listing file (with symbol info mixed in) from the .elf file, which is the build step just before .hex. Can you build again on both platforms, and post your .lst file(s)?

avr-objdump -h -S sketch_081230a.elf > sketch_081230a.lst

I've done this for OSX, can you do one for the broken sketch A?

B is the bad one...

http://82smugglers.com/misc/sketch_081230b.lst

A works...
http://82smugglers.com/misc/sketch_081230a.lst

Just to avoid confusion, it might be better to test a script that calls just rand(void) and random(void) -- both of which are misbehaving standard library functions -- and not random(int x), which is the Arduino function that only indirectly calls libc's rand().

Also, calling the seeding functions in the test program muddy the waters unnecessarily.

I am curious to find out why these two functions misbehave and whether there might not be other libc functions that are defective.

Mikal

Just for completeness, could you run "avr-gcc --version" ?
(is there a similar command that will print the versions of all the
libraries involved ?)

The macosx arduino 12 has gcc 4.3.0

avr-gcc (GCC) 4.3.0 as well...

mikalhart, I'll make a more direct rand call after work today.. (no boss == short workday.. woohoo)

It doesn't matter, mikalhart.

random() calls rand(); rand() calls an internal do_rand().

In A and B, all of the incidental calls like srand(), rand(), random() are identical bytecodes. The do_rand() is significantly different.

As I mentioned earlier, the usual PRNG approach is more bit-fiddling than what I would call real math, and I expect the bit fiddling math just works out to be wrong in one library or the other.

The do_rand() in B uses more convenience routines to do the prologue and epilogue, but that probably isn't breaking the values.

The two routines are using significantly different operations to move the basic operands into place before starting the math. This is typical when a compiler's optimizer gets employed, so maybe one libc was built with an optimizer enabled, while the other was not.

The do_rand() in A uses a routine called __udivmodsi4 twice. In the same fashion, the do_rand() in B uses a routine called __divmodsi4. Signed vs unsigned division is probably the culprit here.

Hi Halley,

It doesn't matter... random() calls rand();

I'm just trying to avoid confusing people between Arduino's random(int), which does indeed call rand(), and libc's less-known cousin random() which doesn't, but is broken in the same way as rand(). It calls do_random(). (See random.c.)

If we were going to try to trace through the routines, it would be much better if they started with identical seeds, hence the admonition to avoid calling srand or srandom.

That said, I think you are probably on to something with the do_rand() analysis. Nice work! Do we have the wherewithal to push this awful bug back to its source and get it fixed?

Thanks, Halley!

Mikal

mikalhart, no worries, wasn't trying to be dismissive.

As for getting it fixed upstream, I guess someone has to contact the avr-gcc developers to point out the discrepancy. Showing them the two listing files above, asking them to look at code at <do_rand> and THEN a link to this whole discussion, should be enough for them to track down the problem.

Yeah, and the problem affects do_random() as well. My fear is that if this problem affects these two core library functions, what others might be affected that we haven't discovered!

I'll investigate how to post this to the avr libc developers.

Mikal

Before I post a bug report to the avr-libc developers' forum let me ask our Linux users a question: when you install Arduino-0012, do we build the libc locally, or does it come precompiled? I'm trying to assess whether or not the bug might be a problem with some build scripts under our (Arduino's) control.

Mikal

Well both of my examples were done using Aurduino-0012. Not sure if that helps with your question.

I installed all the avr stuff from the Ubuntu repository so it was precompiled. The linux Arduino tar file only contains avrdude and avrdude.conf

Thanks, Veronica. So can we now say definitively that avr-libc is definitely being provided by the Linux distribution and not by Arduino?

I posted the bug report on the avr-libc-dev forum (avr-libc-dev (thread)), and they ask the following questions:

  • Which Linux distribution does the problem show up on?
  • Who is the maintainer of the AVR GCC toolchain on that Linux distribution?
  • Which version of AVR GCC is being built? (Is it 4.3.0?)
  • How is the AVR GCC toolchain being built? What patches are being used? What is the configuration command line?

Can someone using Linux -- especially on a distribution known to be failing -- answer these?

Mikal

@Mikal....This is the uname -a from the distro that started this thread.

Linux pat-desktop 2.6.27-9-generic #1 SMP Thu Nov 20 22:15:32 UTC 2008 x86_64 GNU/Linux

If you would like more information please let me know.

Pat

Forgot to add this:

pat@pat-desktop:~$ locate avr-gcc
/usr/bin/avr-gcc
/usr/bin/avr-gcc-4.3.0
/usr/bin/avr-gccbug
/usr/share/man/man1/avr-gcc-4.0.2.1.gz
/usr/share/man/man1/avr-gcc.1.gz
/usr/share/man/man1/avr-gccbug.1.gz
pat@pat-desktop:~$

Thanks, Patzak. Is there any way to determine the version of the avr-libc module?

Mine are:
Ubuntu 8.10 (Intrepid Ibex)
avr-libc 1:1.6.2-1
avr-gcc 1:4.3.0-2

Maintainer: Ubuntu MOTU Developers

Linux main 2.6.27-11-generic #1 SMP Fri Dec 19 16:29:35 UTC 2008 x86_64 GNU/Linux

BTW, I just installed the following files from debian sid and now the random function works as expected:

binutils-avr_2.18-4_amd64.deb
avr-libc_1.6.2.cvs20080610-2_all.deb
gcc-avr_4.3.2-1_amd64.deb

I still need to test that this doesn't break something else instead.

HTH

Ver

Installing the updated packages from sid as described here fixes the problem. I'm not sure if that's been mentioned in this thread yet.

Oops, it's right there. Nevermind.

One thing that wasn't mentioned is that you can find these packages on http://packages.debian.org/.