namhyung / uftrace

Function graph tracer for C/C++/Rust/Python
https://uftrace.github.io/slide/
GNU General Public License v2.0
3.07k stars 474 forks source link

Weird interaction with ffmpeg #1694

Open Philius opened 1 year ago

Philius commented 1 year ago

If I run

ffmpeg -y -hide_banner -input_format mjpeg -thread_queue_size 128 -i /dev/video0 \
-f pulse -thread_queue_size 128 -i alsa_input.usb-HD_WEB_CAMERA_HD_WEB_CAMERA_SN0001-02.mono-fallback -ac 1 -c:v h264 -t 00:00:05 ffmpeg.mkv

then it works as expected, but with

uftrace record --nest-libcall \
ffmpeg -y -hide_banner -input_format mjpeg -thread_queue_size 128 -i /dev/video0 \
-f pulse -thread_queue_size 128 -i alsa_input.usb-HD_WEB_CAMERA_HD_WEB_CAMERA_SN0001-02.mono-fallback -ac 1 -c:v h264 -t 00:00:05 ffmpeg.mkv

I get

/dev/video0: No such file or directory
WARN: child terminated by signal: 11: Segmentation fault

On Debian Bookworm the ffmpeg version is ffmpeg-5.1.2. I compiled it from source to get debugging symbols, lower optimization, frame pointers and -finstrument-functions:

./configure --logfile=../make.txt \
  --disable-static \
  --enable-rpath \
  --enable-nonfree \
  --enable-shared \
  --enable-gpl \
  --enable-version3 \
  --enable-gray \
  --enable-chromaprint \
  --enable-frei0r \
  --enable-ladspa \
  --enable-libass \
  --enable-libcodec2 \
  --enable-libfdk-aac \
  --enable-libflite \
  --enable-libfontconfig \
  --enable-libfreetype \
  --enable-libfribidi \
  --enable-libmodplug \
  --enable-libmp3lame \
  --enable-libopenh264 \
  --enable-libplacebo \
  --enable-libpulse \
  --enable-librubberband \
  --enable-librtmp \
  --enable-libtesseract \
  --enable-libtheora \
  --enable-libtls \
  --enable-libv4l2 \
  --enable-libvidstab \
  --enable-libvorbis \
  --enable-libvpx \
  --enable-libwebp \
  --enable-libx264 \
  --enable-libx265 \
  --enable-libxvid \
  --enable-lv2 \
  --enable-openal \
  --enable-opencl \
  --enable-opengl \
  --enable-openssl \
  --enable-cuda-nvcc \
  --enable-libdrm \
  --enable-libnpp \
  --disable-stripping \
  --enable-ftrapv \
  --extra-cflags='-g -finstrument-functions -DWANT_PROFILER' \
  --optflags='-fno-omit-frame-pointer -O1'

-finstrument-functions requires callback implementations which I did with a header file #included in ffmpeg.c called profiler.h:

#ifndef PROFILER_HPP
#define PROFILER_HPP

void __cyg_profile_func_enter( void *func_address, void *call_site )
    __attribute__ ((no_instrument_function));

void __cyg_profile_func_exit ( void *func_address, void *call_site )
    __attribute__ ((no_instrument_function));

void __cyg_profile_func_enter( void * This, void *callsite )
{
}

void __cyg_profile_func_exit( void * This, void *callsite )
{
}
#endif // PROFILER_HPP
namhyung commented 1 year ago

I'm not sure why you need to define the functions. If you define those functions in the ffmpeg, it won't call the external functions in uftrace (libmcount.so).

Anyway, there're a lot of reasons it can go wrong. You can limit functionality to avoid the trouble. First, try not to use --nest-libcall.

Philius commented 1 year ago

I didn't know I could just leave the implementations out completely. With them removed it still builds and runs on its own - good to know. I tried not using --nest-libcall. It appears to be the reason for the problem. I thought I needed it to trace the libraries ffmpeg uses - that's where all the good stuff is. It still appears to be showing library calls so that's good for me. I tried uftrace graph --srcline > uftrace.txt but the file and line number information isn't displayed, even though I changed -g to -ggdb in the configure script call above. It isn't clear if you need to re-run uftrace record to get file names and line numbers. I tried both with and without - no luck.

You could try v4l2loopback to turn your desktop into a simulated camera if you don't have a real camera and mic.

Anything else you need, I'm glad to help.

namhyung commented 1 year ago

I'm happy it worked for you.

As far as the srcline is concerned, you need to run uftrace record with --srcline option first. Other analysis commands like uftrace replay or uftrace graph cannot use the info if it's not recorded.

honggyukim commented 1 year ago

you need to run uftrace record with --srcline option first.

How about making --srcline enabled by default just like we did it for python tracing? This might reduce confusion to general users.

namhyung commented 1 year ago

Unlike Python, it needs to parse the DWARF info separately which might take some time and it would delay the start of target program.

honggyukim commented 1 year ago

Maybe we can measure the time for DWARF parsing and think again. It might not be that serious as we concerns.