Bug Report: IntegerDivideByZero Core 1 Panic in WaveformGenerator::setFrequency when called before SoundGenerator::attach
Note from the author: I am not an expert in ESP32 internals. This entire debugging process, root cause analysis, and the following report were conducted by my AI coding assistant, Gemini 3.1 Pro High, working within the Google Antigravity IDE.
Description
When creating a WaveformGenerator (e.g., SineWaveformGenerator) and immediately setting its frequency using setFrequency(int value) before attaching it to the SoundGenerator via soundGenerator.attach(), the ESP32 crashes instantly with a Guru Meditation Error: Core 1 panic'ed (IntegerDivideByZero). Exception was unhandled.
This happens because the base WaveformGenerator constructor initializes m_sampleRate to 0. When setFrequency is called, it executes the following formula:
m_phaseInc = (((uint32_t)m_frequency * 256) << 11) / sampleRate();
Since sampleRate() is 0, this causes a hardware divide-by-zero exception. m_sampleRate is only properly updated later when soundGenerator.attach(WaveformGenerator * value) is invoked.
The Misleading Stack Trace
This bug was particularly difficult to track down because the exception handler on the ESP32 (Xtensa architecture without a frame pointer) unwinds the stack incorrectly. The resulting backtrace almost always points to _vfiprintf_r or vsnprintf (if there was any recent UI text formatting in FabGL, such as uiLabel::setTextFmt), making it look like a string formatting bug or a memory corruption in newlib.
Steps to Reproduce
- Create a
SineWaveformGenerator object.
- Call
setFrequency(440) on it.
- Do not call
soundGenerator.attach() before setting the frequency.
- The ESP32 will reboot in a loop with an
IntegerDivideByZero panic.
Snippet that crashes:
auto sineGen = new fabgl::SineWaveformGenerator();
sineGen->setFrequency(440); // CRASH! IntegerDivideByZero
soundGenerator.attach(sineGen);
Workaround / Fix:
Manually setting the sample rate before calling setFrequency() prevents the crash:
auto sineGen = new fabgl::SineWaveformGenerator();
sineGen->setSampleRate(16000); // or whatever your SoundGenerator sample rate is
sineGen->setFrequency(440); // Works perfectly
soundGenerator.attach(sineGen);
Environment Details
- FabGL Version: 1.0.9
- Arduino Core for ESP32: 2.0.11
- Hardware: ESP32-D0WD-V3 (revision v3.0)
- Board Config: PartitionScheme=huge_app, PSRAM=enabled
Suggested Fix in FabGL
In src/devdrivers/soundgen.cpp (and other generator files), the setFrequency methods could be protected against a zero sample rate to prevent hard crashes. For example:
void SineWaveformGenerator::setFrequency(int value) {
if (m_frequency != value) {
m_frequency = value;
if (sampleRate() > 0) {
m_phaseInc = (((uint32_t)m_frequency * 256) << 11) / sampleRate();
} else {
m_phaseInc = 0; // Or defer the calculation until attach() is called
}
}
}
Relevant Commit
You can see the exact workaround applied in my project repository here:
Commit: fabgl fix
Thank you for this amazing library!
Bug Report:
IntegerDivideByZeroCore 1 Panic inWaveformGenerator::setFrequencywhen called beforeSoundGenerator::attachNote from the author: I am not an expert in ESP32 internals. This entire debugging process, root cause analysis, and the following report were conducted by my AI coding assistant, Gemini 3.1 Pro High, working within the Google Antigravity IDE.
Description
When creating a
WaveformGenerator(e.g.,SineWaveformGenerator) and immediately setting its frequency usingsetFrequency(int value)before attaching it to theSoundGeneratorviasoundGenerator.attach(), the ESP32 crashes instantly with aGuru Meditation Error: Core 1 panic'ed (IntegerDivideByZero). Exception was unhandled.This happens because the base
WaveformGeneratorconstructor initializesm_sampleRateto0. WhensetFrequencyis called, it executes the following formula:Since
sampleRate()is0, this causes a hardware divide-by-zero exception.m_sampleRateis only properly updated later whensoundGenerator.attach(WaveformGenerator * value)is invoked.The Misleading Stack Trace
This bug was particularly difficult to track down because the exception handler on the ESP32 (Xtensa architecture without a frame pointer) unwinds the stack incorrectly. The resulting backtrace almost always points to
_vfiprintf_rorvsnprintf(if there was any recent UI text formatting in FabGL, such asuiLabel::setTextFmt), making it look like a string formatting bug or a memory corruption innewlib.Steps to Reproduce
SineWaveformGeneratorobject.setFrequency(440)on it.soundGenerator.attach()before setting the frequency.IntegerDivideByZeropanic.Snippet that crashes:
Workaround / Fix:
Manually setting the sample rate before calling
setFrequency()prevents the crash:Environment Details
Suggested Fix in FabGL
In
src/devdrivers/soundgen.cpp(and other generator files), thesetFrequencymethods could be protected against a zero sample rate to prevent hard crashes. For example:Relevant Commit
You can see the exact workaround applied in my project repository here:
Commit: fabgl fix
Thank you for this amazing library!