網頁

2023年3月29日 星期三

檢查 memory leak

安裝 valgrind
$ sudo apt update
$ sudo apt install snapd
$ sudo snap install valgrind --classic

$ gcc -g -o debug_prog debug_prog.c
$ g++ -g -o debug_prog debug_prog.c

開啟兩個 terminal
$ valgrind --vgdb=yes --vgdb-error=0 --tool=memcheck --leak-check=full ./debug_prog

$ gdb ./debug_prog
(gdb) target remote | vgdb
(gdb) break linenum
(gdb) next
(gdb) step
(gdb) monitor leak_check full reachable any
(gdb) kill
(gdb) quit

若只是單純檢查 memory leak
$ valgrind --tool=memcheck --leak-check=full ./debug_prog

suppression 一些錯誤
$ valgrind --tool=memcheck --leak-check=full --gen-suppressions=all ./debug_prog
...
{
   <insert_a_suppression_name_here>
   Memcheck:Leak
   match-leak-kinds: definite
   fun:malloc
   fun:g_malloc
   obj:/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.5600.4
   fun:call_init
   fun:_dl_init
   obj:/lib/x86_64-linux-gnu/ld-2.27.so
}
...

利用上個命令的輸出,產生 local.supp 檔
$ valgrind --tool=memcheck --leak-check=full --supressions=./local.supp ./debug_prog
$ valgrind --tool=memcheck --leak-check=full --gen-suppressions=all --log-file=supp.log --supressions=./local.supp ./debug_prog
$ cat ./supp.log | ./suppressions.sh > local.supp
$ valgrind --tool=memcheck --leak-check=full --supressions=./local.supp --supressions=./gtk.supp ./debug_prog

suppressions.sh 若產生下列錯誤
awk: 34: unexpected character '&'
需改變 awk 的版本為 gawk
$ awk -W version
$ sudo apt-get update
$ sudo apt-get install gawk

去除 definitely loss
== 16,384 bytes in 1 blocks are definitely lost in loss record 1,443 of 1,448
==    at 0x4C330C5: malloc (vg_replace_malloc.c:393)
==    by 0x6A0BBD8: g_malloc (gmem.c:99)
==    by 0x6A1674B: g_quark_init (gquark.c:62)
==    by 0x40108D2: call_init (dl-init.c:72)
==    by 0x40108D2: _dl_init (dl-init.c:119)
==    by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.27.so)

下載 gst.supp 和 glib.supp gtk.supp
https://gitlab.freedesktop.org/gstreamer/common/-/blob/master/gst.supp
https://github.com/GNOME/glib/blob/main/tools/glib.supp
https://gist.github.com/pendingchaos/81feddb95c06aeb58e2f

Makefile 的
CFLAGS+= -g -O0

安裝 libglib 的 debug symbols 版本
$ echo "deb http://ddebs.ubuntu.com $(lsb_release -cs) main restricted universe multiverse
deb http://ddebs.ubuntu.com $(lsb_release -cs)-updates main restricted universe multiverse
deb http://ddebs.ubuntu.com $(lsb_release -cs)-proposed main restricted universe multiverse" | \
sudo tee -a /etc/apt/sources.list.d/ddebs.list
$ sudo apt install ubuntu-dbgsym-keyring
$ sudo apt update
$ sudo apt install libglib2.0-bin-dbgsym libglib2.0-0-dbgsym libglib2.0-dev-bin-dbgsym


export G_DEBUG=gc-friendly
export G_SLICE=always-malloc

valgrind -v --time-stamp=yes --tool=memcheck --leak-check=full \
  --gen-suppressions=all --log-file=supp.log \
  --suppressions=./glib.supp \
  --suppressions=./gst.supp \
  --suppressions=./gtk.supp \
  ./main

常用觀測記憶體使用狀態命令
$ while true; do echo -n `date +"%Y/%m/%d %H:%M:%S"`" " | tee -a aaa.log ; grep "VmRSS" /proc/26885/status | tee -a aaa.log ; sleep 60 ; done
$ watch "grep 'VmRSS\|VmPeak\|VmData\|VmStk\|VmExe\|VmLib\|Threads' /proc/26885/status" 


2023年3月21日 星期二

deepstream create_pipeline 分析

/opt/nvidia/deepstream/deepstream-6.0/sources/apps/sample_apps/deepstream-app/deepstream_app.c
create_pipeline (AppCtx * appCtx,
    bbox_generated_callback bbox_generated_post_analytics_cb,
    bbox_generated_callback all_bbox_generated_cb, perf_callback perf_cb,
    overlay_graphics_callback overlay_graphics_cb)
{
    multi_src_bin = create_multi_source_bin {
        sub_bins[] = create_camera_source_bin | 
            create_uridecode_src_bin | 
            create_rtsp_src_bin | 
            create_uridecode_src_bin_audio;
        sub_bins[] - nvstreammux;
    };
    create_common_elements {
        secondary_gie_bin = create_secondary_gie_bin {
            sub_bins[] = create_secondary_gie {
                secondary_gie = nvinfer | nvinferserver
                if (num_children == 0) {
                    queue - secondary_gie - fakesink
                } else {
                    queue - secondary_gie - tee
                }
            };
            tee - queue
            tee - sub_bins[]...
        };
        dsanalytics_bin = create_dsanalytics_bin {
            queue - nvdsanalytics
        };
        tracker_bin = create_tracking_bin { nvtracker };
        primary_gie_bin = create_primary_gie_bin {
            queue - nvvideoconvert - (nvinfer | nvinferserver) 
        };
        preprocess_bin = create_preprocess_bin {
            queue | nvdspreprocess
        };
        common_elements = nvmsgconv - tee
        {   preprocess_bin - primary_gie_bin - tracker_bin - 
            dsanalytics_bin - secondary_gie_bin - common_elements - 
            tee
        };
        secondary_gie_bin(src) -> bbox_generated_post_analytics_cb()
        sink_elem = preprocess_bin
        src_elem = tee
    };
    dsexample_bin = create_dsexample_bin { 
        queue - nvvideoconvert - capsfilter - dsexample 
    };
    demuxer = { nvstreamdemux };
    instance_bins[] = create_processing_instance {
        osd_bin = create_osd_bin { 
            queue - nvvideoconvert - queue - nvdsosd 
        };
        sink_bin = create_sink_bin {
            sub_bins[] = create_render_bin | 
                create_encode_file_bin | 
                create_udpsink_bin | 
                create_msg_conv_broker_bin
            queue - tee - sub_bins[]
        };
        osd_bin - sink_bin
        (sink)osd_bin -> all_bbox_generated_cb()
        (sink)osd_bin -> overlay_graphics_cb()
    };
    demux_instance_bins[] = create_demux_pipeline {
        osd_bin = create_osd_bin {
            queue - nvvideoconvert - queue - nvdsosd 
        };
        demux_sink_bin = create_demux_sink_bin {
            sub_bins[] = create_render_bin |
                create_encode_file_bin |
                create_udpsink_bin |
                create_msg_conv_broker_bin
            queue - tee - sub_bins[]
        };
        osd_bin - demux_sink_bin
    };
    tiled_display_bin = create_tiled_display_bin {
        queue - nvmultistreamtiler
    };
    if (tiled_display_config.enable) {
        multi_src_bin - (sink_elem-src_elem) - dsexample_bin - tiler_tee
            tiler_tee - nvstreamdemux - demux_instance_bins[]
            tiler_tee - tiled_display_bin - instance_bins[]
    } else {
        multi_src_bin - (sink_elem-src_elem) - dsexample_bin - demuxer - instance_bins[]
    };
};

2023年3月17日 星期五

ubuntu cpu 工作頻率設定

$ sudo apt-get install cpufrequtils
$ cpufreq-info
$ for i in {0..15}
> do
>   sudo cpufreq-set -d 800000 -u 3200000 -c $i
> done
$ watch -n1 "grep Hz /proc/cpuinfo | grep -v model"
$ watch sensors

2023年3月9日 星期四

lftp in wsl

vi ~/.ssh/config
Host 192.168.5.9
        KexAlgorithms +diffie-hellman-group1-sha1
        HostKeyAlgorithms ssh-rsa
        PubkeyAcceptedKeyTypes ssh-rsa

lftp command

set FTP_USER=digichance
set FTP_PASSWD=sh22463458
set FTP_SITE=114.33.245.149
set FTP_PORT=22
rem set FTP_PORT=7010
set FTP_LOCAL=/cygdrive/D/Photo
set FTP_REMOTE=/d:/temp
set FTP_CMD=lftp.exe
set PATH=%PATH%;C:\lftp-4.9.2.win64-openssl\bin
set PUT=Y
set REMOVE_SOURCE=N

set today=%date:~0,10%
set dy=%today:~0,4%
set dm=%today:~5,2%
set dd=%today:~8,2%
set YES_DAY=%dy%%dm%%dd%
call YesDay.bat %YES_DAY%
echo %YES_DAY%
call YesDay.bat %YES_DAY%
echo %YES_DAY%

if "%REMOVE_SOURCE%"=="Y" (
    set REMOVE_CMD=--Remove-source-dirs
) else (
    set REMOVE_CMD=
)
if "%PUT%"=="Y" (
    set FILE_LIST=-R %FTP_LOCAL%/%1 %1
) else (
    set FILE_LIST=%1 %FTP_LOCAL%/%1
)
%FTP_CMD% -c "set sftp:auto-confirm yes;set net:timeout 5;set net:max-retries 3; open -u %FTP_USER%,%FTP_PASSWD% -p %FTP_PORT% sftp://%FTP_SITE%; cd %FTP_REMOTE%; mirror %REMOVE_CMD% %FILE_LIST%; quit"

rem GET YESTERDAY DATE
rem for Windows 2000,XP,2003
rem http://hi.baidu.com/uroot
@echo off

set dt=%1%
rem date format is "YYYYMMDD"

rem set /P dt="Input Date: "

set dy=%dt:~0,4%
set dm=%dt:~4,2%
set dd=%dt:~6,2%

echo %dy%-%dm%-%dd%
if %dm%%dd%==0101 goto L01
if %dm%%dd%==0201 goto L02
if %dm%%dd%==0301 goto L07
if %dm%%dd%==0401 goto L02
if %dm%%dd%==0501 goto L04
if %dm%%dd%==0601 goto L02
if %dm%%dd%==0701 goto L04
if %dm%%dd%==0801 goto L02
if %dm%%dd%==0901 goto L02
if %dm%%dd%==1001 goto L05
if %dm%%dd%==1101 goto L03
if %dm%%dd%==1201 goto L06

if %dd%==02 goto L10
if %dd%==03 goto L10
if %dd%==04 goto L10
if %dd%==05 goto L10
if %dd%==06 goto L10
if %dd%==07 goto L10
if %dd%==08 goto L10
if %dd%==09 goto L10
if %dd%==10 goto L11
set /A dd=dd-1
set dt=%dy%-%dm%-%dd%
goto END
:L10
set /A dd=%dd:~1,1%-1
set dt=%dy%-%dm%-0%dd%
set dd=0%dd%
goto END
:L11
set dt=%dy%-%dm%-09
set dd=09  
goto END

:L02
set /A dm=%dm:~1,1%-1
set dt=%dy%-0%dm%-31
set dm=0%dm%
set dd=31
goto END
:L04
set /A dm=dm-1
set dt=%dy%-0%dm%-30
set dm=0%dm%
set dd=30
goto END

:L05
set dt=%dy%-09-30
set dm=09
set dd=30
goto END
:L03
set dt=%dy%-10-31
set dm=10
set dd=31
goto END
:L06
set dt=%dy%-11-30
set dm=11
set dd=30
goto END
:L01
set /A dy=dy-1
set dt=%dy%-12-31
set dm=12
set dd=31
goto END

:L07
set /A "dd=dy%%4"
if not %dd%==0 goto L08
set /A "dd=dy%%100"
if not %dd%==0 goto L09
set /A "dd=dy%%400"
if %dd%==0 goto L09
:L08
set dt=%dy%-02-28
set dm=02
set dd=28
goto END
:L09
set dt=%dy%-02-29
set dm=02
set dd=29
goto END

:END
rem echo %dt%
set YES_DAY=%dy%%dm%%dd%

2023年3月7日 星期二

install opencv4.6.0 with CUDA for Jetson

參考 https://forums.developer.nvidia.com/t/best-way-to-install-opencv-with-cuda-on-jetpack-5-xavier-nx-opencv-for-tegra/222777
下載 install_opencv4.6.0_jetson.sh 備份如下
#!/bin/bash
#
# Copyright (c) 2022, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA Corporation and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA Corporation is strictly prohibited.
#

version="4.6.0"
folder="workspace"

for (( ; ; ))
do
    echo "Do you want to remove the default OpenCV (yes/no)?"
    read rm_old

    if [ "$rm_old" = "yes" ]; then
        echo "** Remove other OpenCV first"
        sudo apt -y purge *libopencv*
break
    elif [ "$rm_old" = "no" ]; then
break
    fi
done


echo "------------------------------------"
echo "** Install requirement (1/4)"
echo "------------------------------------"
sudo apt-get update
sudo apt-get install -y build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
sudo apt-get install -y python3.8-dev python-dev python-numpy python3-numpy
sudo apt-get install -y libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libdc1394-22-dev
sudo apt-get install -y libv4l-dev v4l-utils qv4l2 v4l2ucp
sudo apt-get install -y curl


echo "------------------------------------"
echo "** Download opencv "${version}" (2/4)"
echo "------------------------------------"
mkdir $folder
cd ${folder}
curl -L https://github.com/opencv/opencv/archive/${version}.zip -o opencv-${version}.zip
curl -L https://github.com/opencv/opencv_contrib/archive/${version}.zip -o opencv_contrib-${version}.zip
unzip opencv-${version}.zip
unzip opencv_contrib-${version}.zip
rm opencv-${version}.zip opencv_contrib-${version}.zip
cd opencv-${version}/


echo "------------------------------------"
echo "** Build opencv "${version}" (3/4)"
echo "------------------------------------"
mkdir release
cd release/
cmake -D WITH_CUDA=ON -D WITH_CUDNN=ON -D CUDA_ARCH_BIN="7.2,8.7" -D CUDA_ARCH_PTX="" -D OPENCV_GENERATE_PKGCONFIG=ON -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-${version}/modules -D WITH_GSTREAMER=ON -D WITH_LIBV4L=ON -D BUILD_opencv_python3=ON -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_EXAMPLES=OFF -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local ..
make -j$(nproc)


echo "------------------------------------"
echo "** Install opencv "${version}" (4/4)"
echo "------------------------------------"
sudo make install
echo 'export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH' >> ~/.bashrc
echo 'export PYTHONPATH=/usr/local/lib/python3.8/site-packages/:$PYTHONPATH' >> ~/.bashrc
source ~/.bashrc


echo "** Install opencv "${version}" successfully"
echo "** Bye :)"

將 cv2 加到 python3 中
$ export PYTHONPATH=$PYTHONPATH:/usr/local/lib/python3.8/site-packages
$ python3
>>> import cv2
>>> cnt = cv2.cuda.getCudaEnabledDeviceCount()
>>> cnt
1 表示有 CUDA