As a result of a project I have been working on, I uncovered a couple of issues with the USB code for Teensy 3 in Teensyduino 1.52.

In routine usb_init(), file "cores/teensy3/usb_dev.c", lines 1172 to 1176 are:

Code:
	for (i=0; i <= NUM_ENDPOINTS*4; i++) {
		table[i].desc = 0;
		table[i].addr = 0;
	}
However, the loop should be:
Code:
	for (i=0; i < (NUM_ENDPOINTS+1)*4; i++) {
		table[i].desc = 0;
		table[i].addr = 0;
	}
The existing code leaves the last three buffer descriptor table entries undefined. This results in invalid pointer values being passed to usb_free() when a USB set configuration event occurs. Fortunately, usb_free() is (mostly) protected against invalid pointer values.

Secondly, in file "cores/teensy3/yield.c", line 41:

Code:
	if (Serial.available()) serialEvent();
It is assumed that the first USB serial interface is always defined. This should be surrounded by conditional compilation directives:

Code:
#if defined(USB_SERIAL) || (USB_DUAL_SERIAL) || defined(USB_TRIPLE_SERIAL)
	if (Serial.available()) serialEvent();
#endif
Finally, in file "cores/teensy3/usb_dev.c", lines 1073 to 1076, there is the comment:

Code:
// TODO: implement a per-endpoint maximum # of allocated
// packets, so a flood of incoming data on 1 endpoint
// doesn't starve the others if the user isn't reading
// it regularly
Just to confirm that I have encountered this issue. The solution I adopted for my project was to create separate packet pools for each USB endpoint. There may be better ways of dealing with this.