Bootstrap

基于VSCode的远程调试容器中的代码

一、准备工作

cd /data02/lhh/workspace
sudo cp ~/vscode-server-for-v1.38.1-2020.3.13.tar.gz ./
# sudo cp ../TNN/TNN/TNN-feature_demo  ./
# 报错:cp:omitting
#这是因为TNN-feature_demo目录下还有目录
sudo cp -r ../TNN/TNN/TNN-feature_demo  ./
cd ~
#查看镜像列表
sudo docker images

二、基于镜像生成容器

sudo docker run \
--runtime=nvidia \
--name=TNN-feature_demo1 \
-it \
-v /data02/lhh/TNN-branch:/workspace/TNN-branch \
-p 50014:22 \
--shm-size=20g \
--ulimit memlock=-1 --ulimit stack=67108864 \
--cap-add=SYS_PTRACE --security-opt seccomp=unconfined \
tnn-dev:20.07 \
/bin/bash
#报错:docker:invalid publish opts format(should be name=value
#500012写错了,改为50012
#注意挂载命令不要写错,挂载之前的文件夹到挂载之后的文件夹,:不能有空格

三、更改内网源

接下来需要下载安装openssh-server和gdb,因为不能联网

#查看容器的操作系统
cat /etc/issue
#如果是Ubuntu18.04的操作系统

#查看内网源ip有没有变
#注意查Ip地址是否更新
sudo docker inspect ubuntu1804_repository_server_wzy | grep IPAddress

cd /etc/apt
ls
rm sources.list
echo deb [trusted=yes] http://172.17.0.4/ubuntu_1804_repository ./ > sources.list
rm -r sources.list.d
apt update

四、VScode远程连接

经过步骤二,会进入到容器内部

root@09d0077d04a4:/#
cd ~
cp /workspace/TNN-branch/vscode-server-for-v1.38.1-2020.3.13.tar.gz ./
tar -zxvf vscode-server-for-v1.38.1-2020.3.13.tar.gz


cd /
passwd
123456
apt install openssh-server    #1
#vim /etc/ssh/ssh_config
service ssh restart    #2

#云桌面
#ssh-keygen -t rsa
ssh-copy-id [email protected] -p 50012
yes
123456

如果遇到管道不存在的错误,参考https://blog.csdn.net/baidu_39131915/article/details/116302847
删除本地的连接记录
在这里插入图片描述
也可以尝试,用 powershell或者git bash吧,cmd应该是不行,纯粹的ssh连接,如果这都连不上,就不要说vscode连了
在这里插入图片描述

五、VScode分步调试g++版本

参考

在VSCode中打开工作目录

1、修改launch.json

点击左侧的小瓢虫,点击齿轮,选择g++,选择点击default configure就能自动生成launch.json文件

{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) 启动", //会显示在debug界面的debug名称
            "type": "cppdbg", //指定debug的类型
            "request": "launch",
            "program": "${workspaceFolder}/main.out", // 对应编译生成的可执行文件
            "args": [], // 可执行文件带有的参数,根据可执行文件需要填写
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}", // gdb程序的工作目录
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb", // debug 使用的程序
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "echo" // 该项的值对应任务文件中的label的值,表示在执行debug前先执行编译任务
        }
    ]
}

配置完成保存文件后,就可以看到在vscode的debug界面有一个名为(gdb) 启动的debug按钮了。

2、配置task

(1)按住ctrl+shift+P,打开命令面板;
(2)选择Configure Tasks…,选择Create tasks.json file from templates,之后会看到一系列task模板;
(3)选择others,创建一个task,下面是一个task的示例:

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "echo",
            "type": "shell",
            "command": "g++",
            "args":[
                "-g", // 必须的参数,指定编译时需要使用gdb调试,否则会出现无法加入断点的问题
                //"main.cpp",
                "${workspaceFolder}/examples/armlinux/src/TNNFaceDetector/TNNFaceDetector.cc",
                //${workspaceFolder}一般指左侧打开的工作目录
                "-o",
                "main.out"
            ]
        }
    ]
}

3、编写测试代码

// main.cpp
#include <stdlib.h>
#include <iostream>
using namespace std;

int main(void) {
  int count = 10;
  for (size_t i = 0; i < count; i++)
  {
    cout << i << endl;
  }
  return 0;
}

调试F5, 不调试直接运行Cltr+F5

成功:
可以在左侧watch栏,敲入变量i
在这里插入图片描述

六、VScode分步调试cmake版本

1、修改工作路径

如果不修改,会默认是编译目录的根目录下的CMakeLists.txt,build文件夹也会建立在根目录下

File—Preferences—Settings在搜索框搜索cmake
Cmake:Source Directory里修改
在这里插入图片描述
Cmake:Build Directory里修改:
在这里插入图片描述
或者直接在./vscode/settings.json里面添加,修改会自动添加:
在这里插入图片描述

2、在vscode添加头文件路径(可选)

Ctrl+Shift+P 打开命令 输入configuration,回车打开 c_cpp_properties.json
在这里插入图片描述
注意:这个配置的作用是帮助显示,仅仅是辅助写代码的,不指导编译,不然vscode会出现很多的波浪线

3、添加CMake kits在这里插入图片描述

4、修改launch.json和tasks.json

{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) 启动", //会显示在debug界面的debug名称
            "type": "cppdbg", //指定debug的类型
            "request": "launch",
            "program": "${workspaceFolder}/examples/armlinux/build/demo_arm_linux_facedetector", 
            // 对应编译生成的可执行文件
            "args": [
            "../../../model/face_detector/version-slim-320_simplified.tnnproto",
            "../../../model/face_detector/version-slim-320_simplified.tnnproto"
            ], // 可执行文件带有的参数,根据可执行文件需要填写
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}/examples/armlinux", // gdb程序的工作目录
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb", // debug 使用的程序
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "echo" // 该项的值对应任务文件中的label的值,表示在执行debug前先执行编译任务
        }
    ]
}
{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "echo",
            "type": "shell",
            "command": "cmake",
            "args":[
                "-g", 
                "${workspaceFolder}/examples/armlinux"
             
            ]
        }
    ]
}

5、CMake Build Debug

依次点击1 2 3
在这里插入图片描述
build的时候报错CMakeLists.txt第5行报错
build的时候报错找不到ldTNN
错误原因都是vscode的找不到TNN_LIB_PATH,把${TNN_LIB_PATH}改成具体路径就可以了

2.1 You cannot attach to a stopped container,start it first

当容器被终止后,想重新进入,基于镜像arm64v8/ubuntu:18.04的容器

sudo docker restart 632ce63eccoa
sudo docker attach 632ce63eccoa

报错:You cannot attach to a stopped container,start it first
没找到解决办法,只能重新构建容器了,原因一样,重新注册就可以了

docker run --rm --privileged multiarch/qemu-user-static:register --reset
sudo docker run \
--runtime=nvidia \
--name=aarch64-demo \
-it \
-v /usr/bin/qemu-aarch64-static:/usr/bin/qemu-aarch64-static \
-v /data02/lhh/TNN/TNN:/workspace/TNN \
-v /data02/lhh/TNN-branch:/workspace/TNN-branch \
-p 50015:22 \
--ulimit memlock=-1 --ulimit stack=67108864 \
--cap-add=SYS_PTRACE --security-opt seccomp=unconfined \
arm64v8/ubuntu:18.04 \
/bin/bash

又遇到错误:standard_init_linux.go:207:exec user process caused "exec format error"
是因为没有执行,记住服务器关机重启之后都要执行这条命令:

docker run --rm --privileged multiarch/qemu-user-static:register --reset

4.1 Connection refused

如果在git bash里遇到Connection refused的问题,重新在远程终端执行:
1 apt install openssh-server
2 service ssh restart

5.1 libpython3.6 (>=3.6.5) but

必须先在容器里安装gdb。
基于镜像tnn-dev:20.0的容器apt install gdb的时候会报错:
Depends:libpython3.6 (>=3.6.5) but it is not going to be installed
Unable to correct problems,you have held broken packages
原因:python版本冲突
解决方法:彻底卸载python3

apt-get remove python3
apt-get remove --auto-remove python3
apt-get purge --auto-remove python3
apt install gdb
cd /usr/bin #会发现gdb

卸载方法参考

5.2 单步调试在断点不停

单步调试在断点不停的问题,是因为建立容器的时候少了这一句话:
--cap-add=SYS_PTRACE --security-opt seccomp=unconfined

6.2 The current CMakeCache.txt directory is different

在执行./build_aarch64.sh时出现错误:CMake Error:The current CMakeCache.txt directory is different than the directory where CMakeCache.txt was created.This may resultin branaries being created in the wrong place

把…/…/scripts/build_aarch64_linux文件夹和build文件夹删除掉重新编译
原因是以前编译的目录和现在的不一样
参考

6.2 error while loading shared libraries:libgomp.so.1

在aarch64进行demo测试时出现
error while loading shared libraries:libgomp.so.1:cannot open shared object file:No such file or directory
在/lib/aarch64-linux-gnu里面添加libgomp.so.1

六、yolov3-tiny的适应性修改

3、clock计时的用法

void main()
{
 clock_t start,finish;
 start = clock();
 .
 .
 .
 finish = clock();
 cout << finish-start <<"/"<< CLOCKS_PER_SEC << "(S)" <<endl;
 }
void main()
{
 
struct timeval start, end;
gettimeofday(&start, NULL);
.
.
.
gettimeofday(&end, NULL);
int64_t abs_timediff = (end.tv_sec - start.tv_sec) * 1000ULL * 1000ULL + end.tv_usec - start.tv_usec;
double sec_timediff = (double)abs_timediff / 1000000;
cout << "Time cost of test() is: " << sec_timediff << "s." << endl;
 }

4、

;