Прошу прощения за то, что разместил вопрос, который задавали много раз (я только что прочитал их 10 страниц), но я не могу найти решение.
Я работаю над многопоточной графической / звуковой программой, используя OpenGL и Portaudio соответственно. Аудиопоток использует созданную мной библиотеку для объектов обработки звука. SIGSEGV происходит примерно в 20% случаев (гораздо меньше при отладке) и происходит при сбросе множества аудиообъектов с новой информацией о потоке (частота дискретизации, размер вектора и т. Д.). Code :: blocks Debugger заявляет, что сбой возникает из разных мест каждый раз, когда возникает сбой.
Это цикл обработки звука:
while(true){
stream->tick();
menuAudio.tick();
{
boost::mutex::scoped_lock lock(*mutex);
if(channel->AuSwitch.resetAudio){
uStreamInfo newStream(channel->AuSwitch.newSrate,
channel->AuSwitch.newVSize, channel->AuSwitch.newChans);
menuAudio.resetStream(&newStream);
(*stream) = newStream;
menuAudio.resetStream(stream);
channel->AuSwitch.resetAudio = false;
}
}
}
Он проверяет информацию из графического потока, сообщающую ему сбросить звук, и запускает функцию resetStream объекта патча, который в основном является вектором для аудиообъектов, и запускает каждый из них:
void uPatch::resetStream(uStreamInfo* newStream)
{
for(unsigned i = 0; i < numObjects; ++i){
/*This is where it reports this error: Program received signal SIGSEGV,
Segmentation fault. Variables: i = 38, numObjects = 43 */
objects[i]->resetStream(newStream);
}
}
Иногда он заявляет, что SIGSEGV исходит из разных мест, но из-за того, что он редко дает сбой при запуске с отладчиком, это единственное, что я мог бы сделать.
Так как объектов так много, я не буду публиковать их код сброса, но в качестве примера:
void uSamplerBuffer::resetStream(uStreamInfo* newStream)
{
audio.set(newStream, false);
control.set(newStream, true);
stream = newStream;
incr = (double)buffer->sampleRate / (double)stream->sampleRate;
index = 0;
}
Где код audio.set:
void uVector::set(uStreamInfo* newStream, bool controlVector)
{
if(vector != NULL){
for(unsigned i = 0; i < stream->channels; ++i)
delete[] vector[i];
delete vector;
}
if(controlVector)
channels = 1;
else
channels = newStream->channels;
vector = new float*[channels];
for(unsigned i = 0; i < channels; ++i)
vector[i] = new float[newStream->vectorSize];
stream = newStream;
this->flush();
}
Я могу предположить, что это проблема с переполнением стека, поскольку это действительно происходит только с большим количеством объектов, и каждый из них работает нормально индивидуально. Тем не менее, сам аудиопоток работает нормально и работает аналогичным образом. Кроме того, цикл objects[i]->resetStream(newStream);
должен выталкивать стек после каждой функции-члена, поэтому я не могу понять, почему это будет SIGSEGV.
Любые наблюдения / рекомендации?
РЕДАКТИРОВАТЬ:
Это была неправильно удаленная проблема с памятью. Application Verifier указывал на ошибку в момент возникновения ошибки, а не на случайные ошибки, которые были определены как происходящие из других мест. Проблема заключалась в функции настройки потока uVector, поскольку цель класса - для аудио векторов, использующих многомерные массивы с использованием stream->channels
, с возможностью использования одномерных массивов для управляющих сигналов. При удалении для перераспределения памяти я случайно установил все uVectors независимо от типа для удаления с помощью stream-> channels.
if(vector != NULL){
for(unsigned i = 0; i < stream->channels; ++i)
delete[] vector[i];
delete vector;
}
Где это должно было быть:
if(vector != NULL){
for(unsigned i = 0; i < this->channels; ++i)
delete[] vector[i];
delete vector;
}
Таким образом, он удалял память, к которой не должен иметь доступа, что приводило к повреждению кучи. Я удивлен, что segfault не происходил более регулярно, так как это кажется серьезной проблемой.