Commit 6a05fc06 authored by Stefan Westerfeld's avatar Stefan Westerfeld

Merge branch 'extra-debugging'

* extra-debugging:
  Avoid out-of-bounds access via std::vector::operator[].
	This triggered C++ STL debug checks, and actually is undefined behaviour,
	although it didn't really cause any problems so far.
  Free fft plans at exit to make address sanitizer happy.
  Add build options for address sanitizer and C++ STL debug checks.
Signed-off-by: Stefan Westerfeld's avatarStefan Westerfeld <stefan@space.twc.de>
parents 1eabbe22 ee4af482
......@@ -90,6 +90,27 @@ AC_DEFINE_UNQUOTED(HAVE_FFMPEG, $HAVE_FFMPEG, [whether ffmpeg libs are available
AM_CONDITIONAL([COND_WITH_FFMPEG], [test "x$with_ffmpeg" != "xno"])
dnl -------------------------------------------------------------------------
dnl -------------------- address sanitizer ----------------------------------
AC_ARG_ENABLE([asan], [AS_HELP_STRING([--enable-asan], [build using address sanitizer])],
[
CXXFLAGS="$CXXFLAGS -fsanitize=address -fno-omit-frame-pointer -fstack-protector-all -fno-inline"
LDFLAGS="$LDFLAGS -lasan"
],
[
enable_asan=no
])
dnl -------------------------------------------------------------------------
dnl -------------------- glibcxx assertions ----------------------------------
AC_ARG_ENABLE(debug-cxx,AS_HELP_STRING([--enable-debug-cxx], [setup compiler flags to do C++ STL debug checks]),
[
CXXFLAGS="$CXXFLAGS -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC"
],
[
enable_debug_cxx=no
])
dnl -------------------------------------------------------------------------
# need c++14 mode
AX_CXX_COMPILE_STDCXX_14(ext)
......@@ -111,4 +132,6 @@ echo
echo "---------------------------------------------------------------------------"
echo "$PACKAGE_NAME $PACKAGE_VERSION"
echo "---------------------------------------------------------------------------"
echo " * use ffmpeg libs: $with_ffmpeg (required for HLS)"
echo " Use address sanitizer. .: $enable_asan (for debugging)"
echo " Use stdc++ debug mode .: $enable_debug_cxx (for debugging)"
echo " Use ffmpeg libs. . . . .: $with_ffmpeg (required for HLS)"
......@@ -26,9 +26,27 @@ using std::vector;
using std::complex;
using std::map;
static struct FFTPlanMap
{
std::map<size_t, fftwf_plan> fft_plan;
std::map<size_t, fftwf_plan> ifft_plan;
~FFTPlanMap()
{
auto free_plans = [] (auto& pmap)
{
for (auto it = pmap.begin(); it != pmap.end(); it++)
{
fftwf_destroy_plan (it->second);
}
pmap.clear();
};
free_plans (fft_plan);
free_plans (ifft_plan);
}
} fft_plan_map;
static std::mutex fft_planner_mutex;
static std::map<size_t, fftwf_plan> fft_plan_map;
static std::map<size_t, fftwf_plan> ifft_plan_map;
FFTProcessor::FFTProcessor (size_t N)
{
......@@ -40,11 +58,11 @@ FFTProcessor::FFTProcessor (size_t N)
m_out = static_cast<float *> (fftwf_malloc (sizeof (float) * N_2));
/* plan if not done already */
fftwf_plan& pfft = fft_plan_map[N];
fftwf_plan& pfft = fft_plan_map.fft_plan[N];
if (!pfft)
pfft = fftwf_plan_dft_r2c_1d (N, m_in, (fftwf_complex *) m_out, FFTW_ESTIMATE | FFTW_PRESERVE_INPUT);
fftwf_plan& pifft = ifft_plan_map[N];
fftwf_plan& pifft = fft_plan_map.ifft_plan[N];
if (!pifft)
pifft = fftwf_plan_dft_c2r_1d (N, (fftwf_complex *) m_in, m_out, FFTW_ESTIMATE | FFTW_PRESERVE_INPUT);
......
......@@ -110,7 +110,7 @@ SFOutputStream::write_frames (const vector<float>& samples)
}
sf_count_t frames = samples.size() / m_n_channels;
sf_count_t count = sf_writef_int (m_sndfile, &isamples[0], frames);
sf_count_t count = sf_writef_int (m_sndfile, isamples.data(), frames);
if (sf_error (m_sndfile))
return Error (sf_strerror (m_sndfile));
......
......@@ -136,7 +136,7 @@ StdoutWavOutputStream::write_frames (const vector<float>& samples)
m_raw_converter->to_raw (samples, output_bytes);
fwrite (&output_bytes[0], 1, output_bytes.size(), stdout);
fwrite (output_bytes.data(), 1, output_bytes.size(), stdout);
if (ferror (stdout))
return Error ("write sample data failed");
......
......@@ -214,9 +214,9 @@ public:
{
const size_t synth_frame_sz = Params::frame_size * n_channels;
/* move frame 1 and frame 2 to frame 0 and frame 1 */
std::copy (&synth_samples[synth_frame_sz], &synth_samples[synth_frame_sz * 3], &synth_samples[0]);
std::copy (synth_samples.begin() + synth_frame_sz, synth_samples.end(), synth_samples.begin());
/* zero out frame 2 */
std::fill (&synth_samples[synth_frame_sz * 2], &synth_samples[synth_frame_sz * 3], 0);
std::fill (synth_samples.begin() + synth_frame_sz * 2, synth_samples.end(), 0);
for (int ch = 0; ch < n_channels; ch++)
{
/* mix watermark signal to output frame */
......@@ -418,7 +418,7 @@ public:
}
uint start = 0;
do
while (start != frames.size() / n_channels)
{
const int out_count = Params::frame_size;
float out[out_count * n_channels];
......@@ -435,7 +435,6 @@ public:
start = frames.size() / n_channels - m_resampler.inp_count;
}
while (start != frames.size() / n_channels);
}
vector<float>
read_frames (size_t frames)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment