Strange bug in AudioStream.h

Tactif CIE

Well-known member
I know it's not a typical use case but to help me debugging my app I've coded a small test suite.
So, in a real app I should (and I plan to) avoid instantiating and deleting AudioConnection instances, and in my app the AudioStream instances a kept while the app is running.

But in my test cases I don't. For each test suite I need to create new instances of my AudioModule class, which in turn creates AudioConnection instances and because each AudioModule instance own 2 AudioStream members, those ones are destroyed at the end of the test suite.
Dunno if I'm very clear, but whatever.

Then I created a small sketch that reproduces the problem

Code:
#include <Arduino.h>
#include <Audio.h>

extern "C" char *sbrk(int incr);

int count = 0;

int free_ram() {
  char top;
  return &top - reinterpret_cast<char*>(sbrk(0));
}

void setup() {
  AudioMemory(120);
  Serial.begin(112500);
  delay(1000);
}

void one_turn() {
  AudioOutputUSB usbOutput;
  AudioInputUSB usbInput;
  AudioConnection *cnx = new AudioConnection(usbInput, usbOutput);
  delete cnx;
}

void loop() {
  int d = random(0, 50);
  one_turn();
  delayMicroseconds(d);
  Serial.printf("%10i %i %3i %i\n", count++, AudioStream::memory_used, d, free_ram());
}

This is basically what happen in my test suite.
Run this sketch, you'll go up to millions iterations without a glitch.

Then just make this change and comment the line delayMicroseconds(d);

Bam ! One turn and freeze.

With the help of my poor man fault handler I managed to find where my test suite crashed, the offending line being https://github.com/PaulStoffregen/cores/blob/57bc3456bac2809e1d1448a59f81959acf863f95/teensy3/AudioStream.h#L141
And got catched as a BUS FAULT

Then modify the AudioStream.h file around line 141 as

Code:
Serial.println("In");
for (p=first_update; p->next_update; p = p->next_update) {Serial.printf("%X\n", p);}
Serial.println("Out");

Run the same sketch with delayMicroseconds(d); still commented and you'll get

Code:
In
Out
         0 0  30 217055
In
2002FF98
1E

Seems that we never reach the end of the loop... (and not sure about this : but how p can be 1E ?)

Now, a last point :

A patch have been provided by 'el supremo' : https://forum.pjrc.com/threads/54760-Audio-stops-working-when-repeatedly-creating-disconnecting-AudioConnections?highlight=audio+disconnect

But, no matter if you use the patch or not, the sketch behaves the same.

In my case, because I don't use Arduino environment I tried both the TD 146 core release, and github core master with the same results. The sketch in this post crashes the same way, both in Arduino env and in my Makefile custom build

Environment is :
- TD 146 or Custom Makefile + github core master branch
- Teensy 3.6
- Serial monitoring with tycmd monitor --reconnect --raw
- Mac OS Sierra (for USB)

Dunno if this post is bullet proof in any ways but would like to hear your advice about this ;-)
 
I fixed the problem by editing AudioStream.h and adding a dtor to AudioStream class - May be bad done but at least all my test suites passe, and new / delete of AudioStream instances does not crash anymore - I tested with 10 millions alloc/dealloc, there's only one memory leak of the audio buffer (but it happen only once after few iterations), I can live with it ;-)

Code:
~AudioStream() {
		AudioStream *p, *prev;
                __disable_irq();
		if(first_update) {			
			prev = first_update;
			for (p=first_update; p != this; p = p->next_update) {
					prev = p;
				}
			if(prev != p) 
				prev->next_update = p->next_update;
			else
				first_update = NULL;			
		}
                __enable_irq();
}
 
Back
Top