C Solved - Segmentation fault (core dumped) - When running simple OpenCV C/C++ compiled code.

Hello,

I am reading the book: "OpenCV " - 2nd edition - By Adrian Kaehler & Gary Bradski.

Right at the very first code example in the book, “First Program - Display a Picture”, I get an error: Segmentation fault (core dumped).

Here is the code example from the book:
Example 2-2: A simple OpenCV program that loads an image from disk and displays it on the screen
C++:
#include "opencv2/highgui/highgui.hpp"

using namespace cv;

int main( int argc, char** argv )
{
  Mat img = imread( argv[1], -1 );

    if( img.empty() ) return -1;

    namedWindow( "Example2", WINDOW_AUTOSIZE );

    imshow( "Example2", img );

    waitKey( 0 );

    destroyWindow( "Example2" );
}

I used clang to compile the code using:

clang++ -g opencv_1.cpp -o opencv_1 $(pkg-config --cflags --libs opencv4) -I /usr/local/include/

I did not get any errors during and after compilation.

When I run the compiled code using:
./opencv_1

I get the following error:
Segmentation fault (core dumped)

Now I have no clue whats causing this error.

Here are the details about my PC:

OS: FreeBSD 13.1-RELEASE-p1 amd64
Shell: sh
Resolution: 3840x2160
DE: Plasma 5.24.6
WM: KWin
Theme: [Plasma], Breeze [GTK2/3]
Icons: [Plasma], breeze-dark [GTK2/3]
Terminal: konsole
CPU: AMD FX-8350 (8) @ 3.991GHz
GPU: Ellesmere [Radeon RX 580]
Memory: 5755MiB / 32684MiB


I have compiled OpenCV 4.5.5_9 from source using:
cd /usr/ports/graphics/opencv/ && make reinstall clean

I have also tried running the OpenCV compiled C++ code using the pkg installation of OpenCV 4.5.5_9 rather than using the compilation of FreeBSD ports source:
pkg install graphics/opencv

Doesn't matter if is use either the pkg or ports version of OpenCV, I get the same error.

Here are some details about the OpenCV which is currently installed.
(Note: this is the compilation version from FreeBSD Ports on graphics/OpenCV):

pkg info opencv

Code:
opencv-4.5.5_9
Name : opencv
Version : 4.5.5_9
Installed on : Fri Aug 26 22:54:00 2022 EDT
Origin : graphics/opencv
Architecture : FreeBSD:13:amd64
Prefix : /usr/local
Categories : graphics
Licenses : BSD3CLAUSE
Maintainer : desktop@FreeBSD.org
WWW : https://www.opencv.org/
Comment : Open Source Computer Vision library
Options :
ATLAS : off
DC1394 : on
EIGEN : on
FFMPEG : off
GDAL : on
GDCM : on
GPHOTO2 : on
GSTREAMER : on
GTK3 : off
HARDENING : off
JASPER : off
JAVA : off
JPEG : on
LTO : off
NOBLAS : off
OPENBLAS : on
OPENCL : on
OPENEXR : on
OPENJPEG : on
PATENTED : off
PNG : on
PROTOBUF : on
PYTHON : on
TBB : off
TESSERACT : off
TIFF : on
V4L : on
VTK : off
VULKAN : on
WEBP : on
XINE : off
Shared Libs required:
libwebp.so.7
libtiff.so.5
libpng16.so.16
libopenjp2.so.7
libopenblas.so.0
libjpeg.so.8
libhdf5.so.200
libharfbuzz.so.0
libgstvideo-1.0.so.0
libgstriff-1.0.so.0
libgstreamer-1.0.so.0
libgstpbutils-1.0.so.0
libgstbase-1.0.so.0
libgstaudio-1.0.so.0
libgstapp-1.0.so.0
libgphoto2_port.so.12
libgphoto2.so.6
libgobject-2.0.so.0
libglog.so.1
libglib-2.0.so.0
libgdcmMSFF.so.3.0
libgdcmDSED.so.3.0
libgdal.so.3
libfreetype.so.6
libdc1394.so.25
libOpenEXR-3_1.so.30
Shared Libs provided:
libopencv_xphoto.so.405
libopencv_xobjdetect.so.405
libopencv_ximgproc.so.405
libopencv_xfeatures2d.so.405
libopencv_wechat_qrcode.so.405
libopencv_videostab.so.405
libopencv_videoio.so.405
libopencv_video.so.405
libopencv_tracking.so.405
libopencv_text.so.405
libopencv_surface_matching.so.405
libopencv_superres.so.405
libopencv_structured_light.so.405
libopencv_stitching.so.405
libopencv_stereo.so.405
libopencv_shape.so.405
libopencv_sfm.so.405
libopencv_saliency.so.405
libopencv_rgbd.so.405
libopencv_reg.so.405
libopencv_rapid.so.405
libopencv_quality.so.405
libopencv_plot.so.405
libopencv_photo.so.405
libopencv_phase_unwrapping.so.405
libopencv_optflow.so.405
libopencv_objdetect.so.405
libopencv_ml.so.405
libopencv_mcc.so.405
libopencv_line_descriptor.so.405
libopencv_intensity_transform.so.405
libopencv_imgproc.so.405
libopencv_imgcodecs.so.405
libopencv_img_hash.so.405
libopencv_highgui.so.405
libopencv_hfs.so.405
libopencv_hdf.so.405
libopencv_gapi.so.405
libopencv_fuzzy.so.405
libopencv_freetype.so.405
libopencv_flann.so.405
libopencv_features2d.so.405
libopencv_face.so.405
libopencv_dpm.so.405
libopencv_dnn_superres.so.405
libopencv_dnn_objdetect.so.405
libopencv_dnn.so.405
libopencv_datasets.so.405
libopencv_core.so.405
libopencv_ccalib.so.405
libopencv_calib3d.so.405
libopencv_bioinspired.so.405
libopencv_bgsegm.so.405
libopencv_barcode.so.405
libopencv_aruco.so.405
libopencv_alphamat.so.405
Annotations :
FreeBSD_version: 1301000
cpe : cpe:2.3:a:opencv:opencv:4.5.5:::::freebsd13:x64:9
Flat size : 96.8MiB

Here is the core dump file using gdb to debug back trace the error:

Code:
$ gdb /home/user/OpenCV_1/opencv_1 /home/user/OpenCV_1/opencv_1.core

Reading symbols from /home/user/OpenCV_1/opencv_1...
[New LWP 124122]

warning: Unexpected size of section `.reg-xstate/124122' in core file.
Core was generated by `/home/user/OpenCV_1/opencv_1'.
Program terminated with signal SIGSEGV, Segmentation fault.
Address not mapped to object.

warning: Unexpected size of section `.reg-xstate/124122' in core file.
#0  0x0000000804cd4e84 in strlen () from /lib/libc.so.7

(gdb) bt

#0  0x0000000804cd4e84 in strlen () at /lib/libc.so.7
#1  0x0000000000202a75 in std::__1::char_traits<char>::length(char const*) (__s=0x0) at /usr/include/c++/v1/__string:338
#2  0x0000000000202946 in std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string<decltype(nullptr)>(char const*)
    (this=0x7fffffffe388, __s=0x0) at /usr/include/c++/v1/string:839
#3  0x00000000002026d4 in main(int, char**) (argc=1, argv=0x7fffffffe478) at opencv_1.cpp:21

Anyone have any clue whats causing this error for such basic OpenCV C++ code?
I couldn't find anything on google of any examples of compiling and running any kind of OpenCV code on FreeBSD.

Thanks for any advice.
 
I've no idea what OpenCV is but from the backtrace you shared it seems strlen() is failing on NULL string (which I'm guessing is the __s string being passed by C++ functions.
Looking back at the code you shared and the way you are executing it (without parameters) I'm guessing issue is here:
Code:
  Mat img = imread( argv[1], -1 );
argv[1] (first argument passed to a program) is NULL. Again, just guessing, shouldn't you pass the image as an argument to the program?
 
Hello, Thanks for your reply.
I've no idea what OpenCV is

OpenCV is one of the worlds most used real-time computer vision C++ library, they also have it for python.
Here are some companies who uses OpenCV library: Google, Yahoo, Microsoft, Intel, IBM, Sony, Honda, Toyota

shouldn't you pass the image as an argument to the program?

Yes, you're right I need to pass the image as an argument.

I get a different error now when I pass an image as an argument:
Code:
./opencv_1 lena.jpg
Abort trap (core dumped)

Here is the gdb back trace:
$ gdb /home/user/OpenCV_1/opencv_1 /home/user/OpenCV_1/opencv_1.core

Code:
Abort trap (core dumped)
GNU gdb (GDB) 12.1 [GDB v12.1 for FreeBSD]
Reading symbols from /home/user/OpenCV_1/opencv_1...
[New LWP 128661]

warning: Unexpected size of section `.reg-xstate/128661' in core file.
Core was generated by `./opencv_1 lena.jpg'.
Program terminated with signal SIGABRT, Aborted.
Sent by thr_kill() from pid 3967 and user 1001.

warning: Unexpected size of section `.reg-xstate/128661' in core file.
#0  0x0000000804cb433a in thr_kill () from /lib/libc.so.7

(gdb) bt

#0  0x0000000804cb433a in thr_kill () at /lib/libc.so.7
#1  0x0000000804c2cc74 in raise () at /lib/libc.so.7
#2  0x0000000804cde109 in abort () at /lib/libc.so.7
#3  0x0000000800febe69 in  () at /lib/libcxxrt.so.1
#4  0x00000008041e98f5 in cv::error(cv::Exception const&) () at /usr/local/lib/libopencv_core.so.405
#5  0x00000008041e91a2 in cv::error(int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const*, char const*, int) ()
    at /usr/local/lib/libopencv_core.so.405
#6  0x0000000800db7417 in cv::namedWindow(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) () at /usr/local/lib/libopencv_highgui.so.405
#7  0x00000000002027a9 in main(int, char**) (argc=2, argv=0x7fffffffe478) at opencv_1.cpp:28

I think OpenCV have some trouble to display the image, like literally. Because it could be that OpenCV does not know how to access the window/desktop server to display the image on the KDE desktop environment I am using.

Thanks.
 
Trace shows exception was raised in cv::namedWindow() but that now requires a knowledge of that opencv to know what to expect. As it was exception, didn't it say more about the reason why it quit?

In C and C++, argv contains the program path and any arguments. It is also a NULL terminated array (you can safely assume the last argument will be NULL).
Correct. And hence the strlen crash on NULL with argv[1] when argc is 1.
 
Trace shows exception was raised in cv::namedWindow() but that now requires a knowledge of that opencv to know what to expect. As it was exception, didn't it say more about the reason why it quit?

Oddly no. Just simply says: Abort trap (core dumped)

Thankfully it automatically provides a core file and able to use gdb.
 
One thing that also looks a bit off is the imread call. Instead try.

Code:
Mat img = imread( argv[1]);

imread does take a second parameter but -1 does not look correct. It provides a default argument of IMREAD_COLOR so will use that if you only provide the first argument.

Also, the debug error you are providing doesn't seem to match up with the code. It is saying there is an error on line 28 and yet the snippet you are providing us is shorter than 28 lines. Are you sure you are compiling and running the correct .cpp unit?
 
I'd guess an assert() call somewhere is getting triggered, especially given line 4 of the backtrace, cv:error(cv::Exception const&)
Since it's C++ wrap the code in a try...catch and see if you can dump out what the exception is.
 
One thing that also looks a bit off is the imread call. Instead try.

Code:
Mat img = imread( argv[1]);

imread does take a second parameter but -1 does not look correct. It provides a default argument of IMREAD_COLOR so will use that if you only provide the first argument.

Also, the debug error you are providing doesn't seem to match up with the code. It is saying there is an error on line 28 and yet the snippet you are providing us is shorter than 28 lines. Are you sure you are compiling and running the correct .cpp unit?

Yes same code. I just added some printf() statements to debug which I did not include in the post.

Also I tried:
Code:
Mat img = imread( argv[1]);

Getting same errors.

It seems to me that GTK needs to be enabled on OpenCV, else it will not work to display images or what not.
From my understanding I see that GTK3 is not enabled when doing a pkg info opencv:
GTK3 : off

So I have enabled GTK3 on for OpenCV from ports.
When I make the file I get this error:

Code:
root@user:/usr/ports/graphics/opencv # make 

===>  License BSD3CLAUSE accepted by the user
===>   opencv-4.5.5_9 depends on file: /usr/local/sbin/pkg - found
===> Fetching all distfiles required by opencv-4.5.5_9 for building
===>  Extracting for opencv-4.5.5_9
=> SHA256 Checksum OK for opencv-opencv-4.5.5_GH0.tar.gz.
=> SHA256 Checksum OK for WeChatCV-opencv_3rdparty-a8b69ccc738421293254aec5ddb38bd523503252_GH0.tar.gz.
=> SHA256 Checksum OK for opencv-opencv_contrib-4.5.5_GH0.tar.gz.
=> SHA256 Checksum OK for opencv-ade-v0.1.1f_GH0.tar.gz.
=> SHA256 Checksum OK for opencv-opencv_3rdparty-34e4206aef44d50e6bbcd0ab06354b52e7466d26_GH0.tar.gz.
=> SHA256 Checksum OK for opencv-opencv_3rdparty-fccf7cd6a4b12079f73bbfb21745f9babcd4eb1d_GH0.tar.gz.
=> SHA256 Checksum OK for opencv-opencv_3rdparty-8afa57abc8229d611c4937165d20e2a2d9fc5a12_GH0.tar.gz.
=> SHA256 Checksum OK for opencv-opencv_3rdparty-a56b6ac6f030c312b2dce17430eef13aed9af274_GH0.tar.gz.
/bin/mv /usr/ports/graphics/opencv/work/opencv_contrib-4.5.5 /usr/ports/graphics/opencv/work/opencv-4.5.5/contrib
/bin/mkdir -p /usr/ports/graphics/opencv/work/.build/3rdparty/ade
/bin/mv /usr/ports/graphics/opencv/work/ade-0.1.1f /usr/ports/graphics/opencv/work/.build/3rdparty/ade
/bin/mkdir -p /usr/ports/graphics/opencv/work/.build/downloads/xfeatures2d
cp -f /usr/ports/graphics/opencv/work/opencv_3rdparty-34e4206aef44d50e6bbcd0ab06354b52e7466d26/* /usr/ports/graphics/opencv/work/.build/downloads/xfeatures2d
cp -f /usr/ports/graphics/opencv/work/opencv_3rdparty-fccf7cd6a4b12079f73bbfb21745f9babcd4eb1d/* /usr/ports/graphics/opencv/work/.build/downloads/xfeatures2d
/bin/mkdir -p /usr/ports/graphics/opencv/work/.build/downloads/wechat_qrcode
cp -f /usr/ports/graphics/opencv/work/opencv_3rdparty-a8b69ccc738421293254aec5ddb38bd523503252/* /usr/ports/graphics/opencv/work/.build/downloads/wechat_qrcode/
/bin/mkdir -p /usr/ports/graphics/opencv/work/.build/share/opencv4/testdata/cv/face
cp -f /usr/ports/graphics/opencv/work/opencv_3rdparty-8afa57abc8229d611c4937165d20e2a2d9fc5a12/* /usr/ports/graphics/opencv/work/.build/share/opencv4/testdata/cv/face
/bin/mkdir -p /usr/ports/graphics/opencv/work/.build/3rdparty/ippicv
(cd /usr/ports/graphics/opencv/work/.build/3rdparty/ippicv && /usr/bin/tar -xf /usr/ports/graphics/opencv/work/opencv_3rdparty-a56b6ac6f030c312b2dce17430eef13aed9af274/ippicv/ippicv_2020_lnx_intel64_20191018_general.tgz)
===>  Patching for opencv-4.5.5_9
===>  Applying FreeBSD patches for opencv-4.5.5_9 from /usr/ports/graphics/opencv/files
/usr/bin/sed -i.bak -e 's|/usr/lib/atlas-base|/usr/local/lib|g' /usr/ports/graphics/opencv/work/opencv-4.5.5/cmake/OpenCVFindAtlas.cmake
/usr/bin/sed -i.bak -e 's|/usr/include/atlas|/usr/local/include|g' /usr/ports/graphics/opencv/work/opencv-4.5.5/cmake/OpenCVFindAtlas.cmake
===>   opencv-4.5.5_9 depends on package: opencl>=0 - found
===>   opencv-4.5.5_9 depends on package: py39-numpy>=1.16,1<1.24,1 - found
===>   opencv-4.5.5_9 depends on file: /usr/local/include/linux/videodev2.h - found
===>   opencv-4.5.5_9 depends on package: vulkan-headers>0 - found
===>   opencv-4.5.5_9 depends on file: /usr/local/bin/cmake - found
===>   opencv-4.5.5_9 depends on executable: ninja - found
===>   opencv-4.5.5_9 depends on package: pkgconf>=1.3.0_1 - found
===>   opencv-4.5.5_9 depends on file: /usr/local/libdata/pkgconfig/eigen3.pc - found
===>   opencv-4.5.5_9 depends on package: gstreamer1-plugins>=1.16.2 - found
===>   opencv-4.5.5_9 depends on file: /usr/local/bin/python3.9 - found
===>   opencv-4.5.5_9 depends on package: qt5-buildtools>=5.15 - found
===>   opencv-4.5.5_9 depends on package: qt5-qmake>=5.15 - found
===>   opencv-4.5.5_9 depends on shared library: libfreetype.so - found (/usr/local/lib/libfreetype.so)
===>   opencv-4.5.5_9 depends on shared library: libgflags.so - found (/usr/local/lib/libgflags.so)
===>   opencv-4.5.5_9 depends on shared library: libglog.so - found (/usr/local/lib/libglog.so)
===>   opencv-4.5.5_9 depends on shared library: libharfbuzz.so - found (/usr/local/lib/libharfbuzz.so)
===>   opencv-4.5.5_9 depends on shared library: libhdf5.so - found (/usr/local/lib/libhdf5.so)
===>   opencv-4.5.5_9 depends on shared library: libdc1394.so - found (/usr/local/lib/libdc1394.so)
===>   opencv-4.5.5_9 depends on shared library: libavcodec.so - found (/usr/local/lib/libavcodec.so)
===>   opencv-4.5.5_9 depends on shared library: libgdal.so - found (/usr/local/lib/libgdal.so)
===>   opencv-4.5.5_9 depends on shared library: libgdcmMSFF.so - found (/usr/local/lib/libgdcmMSFF.so)
===>   opencv-4.5.5_9 depends on shared library: libgphoto2.so - found (/usr/local/lib/libgphoto2.so)
===>   opencv-4.5.5_9 depends on shared library: liblapacke.so - found (/usr/local/lib/liblapacke.so)
===>   opencv-4.5.5_9 depends on shared library: libOpenEXR.so - found (/usr/local/lib/libOpenEXR.so)
===>   opencv-4.5.5_9 depends on shared library: libopenjp2.so - found (/usr/local/lib/libopenjp2.so)
===>   opencv-4.5.5_9 depends on shared library: libpng16.so - found (/usr/local/lib/libpng16.so)
===>   opencv-4.5.5_9 depends on shared library: libprotobuf.so - found (/usr/local/lib/libprotobuf.so)
===>   opencv-4.5.5_9 depends on shared library: libtesseract.so - found (/usr/local/lib/libtesseract.so)
===>   opencv-4.5.5_9 depends on shared library: libtiff.so - found (/usr/local/lib/libtiff.so)
===>   opencv-4.5.5_9 depends on shared library: libv4l2.so - found (/usr/local/lib/libv4l2.so)
===>   opencv-4.5.5_9 depends on shared library: libvtkCommonCore-9.1.so - not found
===>  vtk9-9.1.0_4 need to specify gl component with USE_GL.
*** Error code 1

Stop.
make[2]: stopped in /usr/ports/math/vtk9
*** Error code 1

Stop.
make[1]: stopped in /usr/ports/graphics/opencv
*** Error code 1

Stop.
make: stopped in /usr/ports/graphics/opencv
 
Alright, as I expected, it was due to the fact that GTK3 was not enabled.

OpenCV has no way to create GUI applications to display images or live videos contained in a window of some form.

For some reason pkg install opencv does not by default provide binaries that have the GTK3 option enabled (not sure if it could be enabled after installing it).

Anyhow, I installed OpenCV using FreeBSD ports and had to make sure that in make config file that GTK3 option is enabled, since by default it is "off". I then did make && install.

I think OpenCV GTK3 option is disabled by default due to the fact that reading so many programmers preferring to use QT over GTK3. I'll soon switch to QT and disable GTK3 after finishing through the book, since I read that both QT and GTK3 can not be enabled at the same time.

After OpenCV was built with GTK3 enabled, voila, the simple example code in the first post of this thread works.

For those who are curious, I need OpenCV's algorithm of machine vision for motion detection in great dire since I have built a basic practical high performance and high customizability multi-channel security DVRs/NVRs system on Arch Linux (hopefully I'll implement everything on FreeBSD someday once I figure how to do USB cam live stream HEVC transcoding done by GPUs). The core of the system uses FFMPEG and it works great, now I'll integrate it with OpenCV for motion detection (trust me, not a great idea to use any shortcut ways to implement motion detection improvisation using FFMPEG libraries, doesn't work right for true motion detection). All in all, I believe PC based DVR/NVR implementation using FFMPEG with OpenCV are the best. I am using a Lenovo ThinkStation P300 PC which has an Intel i5-4570 3.20GHz CPU with 4GB RAM and 500GB HD which I bought off of ebay for about $100 and it can transcode 4 cameras simultaneously 24/7 at 1080P/30FPS using only about 60% of CPU resource using HEVC encoding after optimizations with the help of two GPUs(one intel integrated GPU and other AMD GPU). Using older PCs and turning them into DVRs/NVRs gives so much freedom and customization compared to commercial DVRs/NVRs for the same price, the only downside is that PCs do tend to take more power consumption and bulkier. However reliability, troubleshooting and being able to repair a DVR/NVR system is always a main priority, you can only do that with PC based DVRs/NVRs easily.

I have tried countless of opensource based DVR/NVR softwares, none of them can provided advanced HEVC transcoding (specially when using multi GPUs) without heavily learning/reverse engineering and modifying their code. I was better off in saving time and getting the exact results needed to just make one myself using FFMPEG from scratch. Took me one month to learn the whole art of FFMPEG.
I'll make a full tutorial on how to build a professional DVR/NVR system using FreeBSD someday. If anyone would like to use a PC for DVR/NVR, obtain an Intel Skylake or newer CPU since it have built-in HEVC transcoding hardware. If you need more transcoding power, obtain an Nvidia GPU which have HEVC transcoding built-in hardware, would need to check their listing on which GPUs have both hardware NVENC and NVDEC for HEVC. Using HEVC encoding is ideal since you can record 24/7 at high resolution and framerate without consumption the entire HD space. Would also like to mention is to not get an AMD GPU since there are no great support for HEVC transcoding as to Nvidia on Linux systems. Note: You'll most likely not need all of these complex transcoding HEVC methods if you are using an IP camera which is able to live stream HEVC video. From my calculations when it comes to price in needing multi channel cameras, you get a better PC DVR/NVR system when using 4K Analog cameras as compared to 4K IP cameras. Proper 4K IP cameras are still super expensive. Using 4K analog cameras requires additional hardware, need to convert the analog signal to be used for the PC, I am using low cost effective universal analog camera to HDMI converter which is then connected to a HDMI to USB converter hooked to the PC.

With all that said, would like to say thanks to everyone who helped me on this thread.
 
I tend to use OpenCV quite a bit but rarely use the highgui (immediate mode ui) stuff. That facility is only really for quick testing (and isn't always provided by some distributions), you might want to instead consider things like outputting to SDL, Xlib, VNC, etc instead if you do need to do anything more with the display than debugging.

Nonetheless, glad you got it figured out; good luck with the project.
 
What is that you are using?

This is the setup diagram:
Vmy9Wi4.jpg

I am using this special analog to HDMI converter, it can take 720P to 4K analog signals of most types (AHD / TVI / CVI / CVBS) and convert to digital HDMI output for $37 from: Amazon.
You can find the same unit for half the price on Ali-Express.

Here is the HDMI to USB 3.0 capture card for $19 from: Amazon.

Good lord, I have spent a good hour typing many information of the PC DVR/NVR system on this post but chrome crashed and I was not able to recover the texts after relaunch and clicking refresh. I explained why 4K Analog camera is currently better than 4K IP camera when it comes to price and picture quality with good stable high frame rates.

It seems I can not access previous drafts saved either.
Not sure if I can somehow obtain the text data written in the reply box from chrome.

Need to figure out how to use Chrome on FreeBSD the proper way because it is consistently crashing. I might as well just migrate to Chromium, but it does not have the extensions I use on Chrome and being lazy to manually update it. Chrome deprecated their syncing services to Chromium.
 
Back
Top