bytedeco / javacv

Java interface to OpenCV, FFmpeg, and more
Other
7.6k stars 1.59k forks source link

With Limiting the memory,segment fatal error made the jvm crash. #2302

Open jiangjiongyu opened 1 day ago

jiangjiongyu commented 1 day ago

Environment Info

Linux 81-228 5.15.0-122-generic
ldd (Ubuntu GLIBC 2.35-0ubuntu3.8) 2.35

Jvm Conf

-Dorg.bytedeco.javacpp.maxPhysicalBytes=4G -Dorg.bytedeco.javacpp.maxBytes=4G -Dorg.bytedeco.javacpp.noPointerGC=false -Dorg.bytedeco.javacpp.logger.debug=true -XX:+PreserveFramePointer

Crash Info

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007ff55263d770, pid=2934393, tid=0x00007ff5ec78d640
# OpenJDK Runtime Environment 8.0
 Problematic frame:
# C  [libavformat.so.60+0x1e4770]  av_write_frame+0x140

---------------  T H R E A D  ------------
Current thread (0x00007ff62bc23000):  JavaThread "xxxx" [_thread_in_native, id=3175554, stack(0x00007ff5ec68e000,0x00007ff5ec78e000)]

siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x0000000000000010

Registers:
RAX=0x0000000000000000, RBX=0x00007ff552ef2478, RCX=0x0000000000000000, RDX=0x0000000000000062
RSP=0x00007ff5ec78c1a0, RBP=0x00007ff5ec78c228, RSI=0x0000000000000000, RDI=0x0000000000000000
R8 =0x00007ff552ef2478, R9 =0x00000006f42114d8, R10=0x00007ff55245e588, R11=0x00007ff55263d630
R12=0x0000000000000000, R13=0x00007ff552ef2470, R14=0x00007ff5ec78c250, R15=0x00007ff62bc23000
RIP=0x00007ff55263d770, EFLAGS=0x0000000000010246, CSGSFS=0x002b000000000033, ERR=0x0000000000000004
  TRAPNO=0x000000000000000e

Top of Stack: (sp=0x00007ff5ec78c1a0)
0x00007ff5ec78c1a0:   0000000000000000 00007ff5ec78c228
0x00007ff5ec78c1b0:   0000000000000000 00007ff552ef2470
0x00007ff5ec78c1c0:   00007ff5ec78c250 00007ff664c185a7
0x00007ff5ec78c1d0:   00007ff5ec78c228 00007ff664c18307
0x00007ff5ec78c1e0:   00007ff664c182c2 00007ff5ec78c1e8
0x00007ff5ec78c1f0:   00007ff552ef2470 00007ff5ec78c250
0x00007ff5ec78c200:   00007ff552ef71e0 0000000000000000
0x00007ff5ec78c210:   00007ff552ef2478 0000000000000000
0x00007ff5ec78c220:   00007ff5ec78c260 00007ff5ec78c2e0
0x00007ff5ec78c230:   00007ff668a8bec4 00000006ee030d08
0x00007ff5ec78c240:   00007ff664c11a56 0000000000000000
0x00007ff5ec78c250:   00000006f42114d8 00007ff668a8bec4
0x00007ff5ec78c260:   00007ff5ec78c310 00007ff668161354
0x00007ff5ec78c270:   0000004900000011 00007ff5ec78c228
0x00007ff5ec78c280:   00000a80000004c0 00000007c0a9fc38
0x00007ff5ec78c290:   00000006f4210df8 00000006f420bc78
0x00007ff5ec78c2a0:   00007ff5ec78c2c0 00000006f4211020
0x00007ff5ec78c2b0:   00000006f42114d8 00007ff668e2cde0
0x00007ff5ec78c2c0:   00000006f4211020 00007ff62bc23000
0x00007ff5ec78c2d0:   00000006f42114d8 00007ff668164246
0x00007ff5ec78c2e0:   00007ff5ec78c340 00007ff668a8ae2c
0x00007ff5ec78c2f0:   00000006f41e3988 00000006c0087070
0x00007ff5ec78c300:   00007ff5ec78c3f0 00007ff664c6d29b
0x00007ff5ec78c310:   00007ff5ec78c3f0 00000006f4211020
0x00007ff5ec78c320:   00000006f4210df8 00000006f420bc78
0x00007ff5ec78c330:   00000006c0087070 00000006c0eb9b30
0x00007ff5ec78c340:   00007ff5ec78c510 00007ff66878288c
0x00007ff5ec78c350:   00000006c0eb9888 00000006c0eb9af0
0x00007ff5ec78c360:   00000006c0eb9ad0 00000006c0eb9970
0x00007ff5ec78c370:   00000007c0097e00 00007ff62bc23000
0x00007ff5ec78c380:   00007ff5ec78c300 00007ff668164246
0x00007ff5ec78c390:   0000000000000000 00007ff668a834d5 

Instructions: (pc=0x00007ff55263d770)
0x00007ff55263d750:   00 00 e8 49 56 ee ff 4c 89 f5 49 89 06 48 85 c0
0x00007ff55263d760:   0f 85 f2 fe ff ff 41 bd f4 ff ff ff eb 9b 66 90
0x00007ff55263d770:   48 8b 47 10 41 bd 01 00 00 00 f6 40 2e 01 74 91
0x00007ff55263d780:   31 f6 ff 50 50 49 8b 7c 24 20 41 89 c5 48 85 ff 

Register to memory mapping:

RAX=0x0000000000000000 is an unknown value
RBX={method} {0x00007ff552ef2478} 'av_write_frame' '(Lorg/bytedeco/ffmpeg/avformat/AVFormatContext;Lorg/bytedeco/ffmpeg/avcodec/AVPacket;)I' in 'org/bytedeco/ffmpeg/global/avformat'
RCX=0x0000000000000000 is an unknown value
RDX=0x0000000000000062 is an unknown value
RSP=0x00007ff5ec78c1a0 is pointing into the stack for thread: 0x00007ff62bc23000
RBP=0x00007ff5ec78c228 is pointing into the stack for thread: 0x00007ff62bc23000
RSI=0x0000000000000000 is an unknown value
RDI=0x0000000000000000 is an unknown value
R8 ={method} {0x00007ff552ef2478} 'av_write_frame' '(Lorg/bytedeco/ffmpeg/avformat/AVFormatContext;Lorg/bytedeco/ffmpeg/avcodec/AVPacket;)I' in 'org/bytedeco/ffmpeg/global/avformat'
R9 =0x00000006f42114d8 is an oop
org.bytedeco.ffmpeg.avformat.AVFormatContext 
 - klass: 'org/bytedeco/ffmpeg/avformat/AVFormatContext'
R10=0x00007ff55245e588: <offset 0x5588> in /home/xx/.javacpp/cache/ffmpeg-6.1.1-1.5.10-linux-x86_64.jar/org/bytedeco/ffmpeg/linux-x86_64/libavformat.so.60 at 0x00007ff552459000
R11=0x00007ff55263d630: av_write_frame+0 in /home/xx/.javacpp/cache/ffmpeg-6.1.1-1.5.10-linux-x86_64.jar/org/bytedeco/ffmpeg/linux-x86_64/libavformat.so.60 at 0x00007ff552459000
R12=0x0000000000000000 is an unknown value
R13=0x00007ff552ef2470 is pointing into metadata
R14=0x00007ff5ec78c250 is pointing into the stack for thread: 0x00007ff62bc23000
R15=0x00007ff62bc23000 is a thread

Stack: [0x00007ff5ec68e000,0x00007ff5ec78e000],  sp=0x00007ff5ec78c1a0,  free space=1016k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [libavformat.so.60+0x1e4770]  av_write_frame+0x140
J 21055 C1 org.bytedeco.javacv.FFmpegFrameRecorder.flush()V (124 bytes) @ 0x00007ff668a8bec4 [0x00007ff668a8b8e0+0x5e4]
C  0x00000006f4211020

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  org.bytedeco.ffmpeg.global.avformat.av_write_frame(Lorg/bytedeco/ffmpeg/avformat/AVFormatContext;Lorg/bytedeco/ffmpeg/avcodec/AVPacket;)I+0
J 21055 C1 org.bytedeco.javacv.FFmpegFrameRecorder.flush()V (124 bytes) @ 0x00007ff668a8bec4 [0x00007ff668a8b8e0+0x5e4]
J 21054 C1 org.bytedeco.javacv.FFmpegFrameRecorder.stop()V (34 bytes) @ 0x00007ff668a8ae2c [0x00007ff668a8ad60+0xcc]

Running Code


public class DataWriter implements Runnable {
    private static final String VIDEO_NAME = "video.mp4";
    private static final int FRAME_RATE_VALUE = 60;

    public static final int AV_CODEC_ID_H264 = 27;

    private final String outputDir;

    private FFmpegFrameRecorder fFmpegFrameRecorder;
    private FFmpegFrameGrabber frameGrabber;

    private final File binaryFile;

    private static final ThreadPoolExecutor THREAD_POOL;

    static {
        THREAD_POOL = new ThreadPoolExecutor(0, 8, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
    }

    public DataWriter(String outputDor, String h264FilePath) {
        this.outputDir = outputDor;
        this.binaryFile = new File(h264FilePath);
    }

    private void initGrabber() throws FFmpegFrameGrabber.Exception {
        this.frameGrabber = new FFmpegFrameGrabber(binaryFile);
        this.frameGrabber.setVideoCodec(AV_CODEC_ID_H264);
        this.frameGrabber.setFrameRate(FRAME_RATE_VALUE);
        frameGrabber.start(true);
    }

    @Override
    public void run() {
        mockRecord(); // execute task here
    }

    public void mockRecord() {
        System.out.println("Intent to write, please wait!");
        try {
            initGrabber();
            int count = 0;
            for (;;) {
                try (Frame frame = frameGrabber.grabFrame()) {
                    if (frame == null) {
                        break;
                    }
                    mockHandleFrame(frame);
                    count++;
                } catch (Exception e) {
                    System.out.println("Play dynamic scenarios to grab frame error:" + e);
                }
            }
            System.out.println("Handle frame finished! And frame count is " + count);
        } catch (Exception e) {
            System.out.println("Take frame error:" + e);
        } finally {
            mockTearDown();
        }
    }

    private void mockHandleFrame(Frame frame) throws Exception {
        if (fFmpegFrameRecorder == null) {
            int w = frame.imageWidth;
            int h = frame.imageHeight;
            if (w > 0 && h > 0) {
                fFmpegFrameRecorder = new FFmpegFrameRecorder(new File(outputDir, VIDEO_NAME), frame.imageWidth,
                        frame.imageHeight);
                fFmpegFrameRecorder.setFrameRate(FRAME_RATE_VALUE);
                fFmpegFrameRecorder.setVideoCodec(AV_CODEC_ID_H264);
                fFmpegFrameRecorder.start();
            }
        }
        if (fFmpegFrameRecorder != null) {
            fFmpegFrameRecorder.record(frame);
        }
    }

    private void mockTearDown() {
        try {
            if (fFmpegFrameRecorder != null) {
                fFmpegFrameRecorder.close();
                fFmpegFrameRecorder = null;
            }
            if (frameGrabber != null) {
                frameGrabber.close();
                frameGrabber = null;
            }
        } catch (IOException e) {
            System.out.println("Frame teardown error:" + e);
        } finally {
            System.out.println("H264 Writer finished!");
        }
    }

    public static void main(String[] args) {
        String path = "xxxxxx";
        String saveDir =  path.concat("/data");
        long duration = 2 * 60 * 60 * 1000; // the time is fake , actual more longer than it
        long startTime = System.currentTimeMillis();
        while (System.currentTimeMillis() - startTime < duration) { // generate a large number of videos
            try {
                File file = new File(saveDir + System.currentTimeMillis());
                if (!file.exists()) {
                    System.out.println(file.getCanonicalPath());
                    if (!file.mkdir()) {
                        System.out.println("Create failed:" + file.getName());
                        continue;
                    }
                }
                DataWriter writer = new DataWriter(file.getCanonicalPath(), path.concat("/a.h264"));
                THREAD_POOL.execute(writer);
                TimeUnit.MILLISECONDS.sleep(10 * 1000);
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }
}
saudet commented 1 day ago

Please try to set the "org.bytedeco.javacpp.nopointergc" system property to "true".