Giter VIP home page Giter VIP logo

blog's People

Contributors

kinzess avatar

Stargazers

 avatar  avatar  avatar

Forkers

qdzhaozx

blog's Issues

Windows下使用MSVC编译FFmpeg

背景:

需要在UE5里编写视频播放插件,系统需要Windows,同时因为UE用的是MSVC,不希望引入mingw那一套,则需要用MSVC编译。
在Linux下编译了很多次,Windows下编译还是头一回,特此记录一下。

原理:

利用mingw模拟Linux环境,使用其各种工具,再将CC编译器改成cl.exe。

步骤如下:

1. 安装MSVC工具链

  • 从官网下载在线安装包vs_BuildTools
  • 直接安装社区版的VisualStudio 2022(新手推荐),或者安装对应的编译组件即可(不推荐)
  • 在环境变量里添加cl.exe的路径,不然使用CMD无法找到:
    1710921606624
  • 选择Path,然后点击编辑
    1710921678580
  • 新建一个路径,找到对应目录的cl.exe即可(一般用Everything搜cl.exe,很方便找路径)
    1710921706681
  • 注意此处选择的,都是x64版本
    D:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.36.32532\bin\Hostx64\x64\cl.exe

2. 安装mingw

  • msys官网直接下载安装即可
  • 安装完后,首先启动MSVC的命令行
    1710922039766
  • 再启动mingw的环境
d:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools>c:
C:\>cd msys64
C:\msys64>msys2_shell.cmd -defterm -full-path -no-start -here -mingw64

1710922538476

3. 编译X264

4. 编译X265

5. 编译libvpl

6. 编译libamf

7. 导入cuda

8. 导入nv-cuda

9. 编译FFmpeg

dd镜像到u盘后校验数据

一般在linux下,会使用dd刻录镜像到u盘。
但是,一般情况下,都不会想到要对数据进行校验。
最近,碰到一个有问题的u盘,刻录好的ubuntu镜像,在安装的过程总会出错。
一开始不知道原因,还以为是镜像有问题。
几番折腾,总算定位到了问题。
使用以下命令校验数据即可:

# image_size=`ls -al xxxx.iso|awk '{print $5}'`
# block_count=`expr ${image_size} / 2048`
# dd if=/dev/usb-device bs=2048 count=${block_count} | md5sum

注1:ISO9660使用的块大小为2KB,所以bs=2048。
注2:一般u盘比iso要大,所以dd必须使用count限制读取的块数量。

mingw编译opencv

最近需要在win10下编译opencv3.4.6,同时支持xfetures2d特性,感觉编译过程还是有点麻烦,需记录一下。

一、下载安装mingw-w64
1、下载地址:
https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/installer/mingw-w64-install.exe

2、安装时注意,Threads必须选posix,如下图:
image
架构可以选i686或者x86_64。

3、安装完成后,需要设置环境变量,添加mingw的bin目录到Path变量里,如下图:
image

二、安装cmake,比较简单,不断下一步即可

三、下载opencv和opencv_contrib的源码,并编译
1、下载地址:
https://codeload.github.com/opencv/opencv/tar.gz/refs/tags/3.4.6
https://codeload.github.com/opencv/opencv_contrib/tar.gz/refs/tags/3.4.6
必须下载opencv_contrib,不然不支持xfetures2d特性。

2、打开cmake-gui,指定源码目录和源码构建目录后,然后点击Configure。
此处选择Mingw编译环境,因为上述已经设置了环境变量,所以直接选择即可,如下图:
image

3、修改编译参数
需要确定开启的参数:
ENABLE_CXX11 //开启c++11
OPENCV_EXTRA_MODULES_PATH //指定到opencv_contrib的module目录

需要确定关闭的参数:
WITH_OPENCL_D3D11_NV //加上这个参数会导致编译失败,提示找不到D3D11的头文件,如果不需要则关闭

可选参数:
CMAKE_BUILD_TYPE // 构建类型,一般输入Release
CMAKE_INSTALL_PREFIX //安装目录,一般不用修改,但是需要记住这个目录,后续用到

修改完成后,需要再次点击Configure,此时cmake会重新配置编译环境,同时从网络下载必须的文件。
注意下载可能会失败,可能需要多次点击Configure。
通过往上翻日志,确定没有提示下载失败,并且界面颜色从红色变成白色后,点击Generate生成编译文件。

四、打开cmd,直接输入mingw32-make -j6编译即可

五、输入mingw32-make install可以安装到刚才指定的目录

六、从安装目录复制文件到D:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\x86_64-w64-mingw32下的相关目录。
注意,因为文件目录不一样,不能直接指定安装目录到mingw下,需要安装好后,自行复制。

通过SSH运行OpenGL程序

最近在使用SSH连接到远程服务器,并运行OpenGL程序时,报错:

- 解决方法:

创建文件/etc/X11/xorg.conf.d/opengl.conf,并输入以下内容:

 Section "ServerFlags"
      Option "AllowIndirectGLX" "on"
      Option "IndirectGLX" "on"
 EndSection

重启系统后解决

Intel无线网卡3165更新内核后无法加载Firmware

在一次更新内核后,无线网卡3165无法加载firmware,错误信息如下:

[    3.423945] r8169 0000:04:00.0 eth0: RTL8168gu/8111gu, f4:8e:38:ec:e7:66, XID 509, IRQ 128
[    3.423984] r8169 0000:04:00.0 eth0: jumbo features [frames: 9200 bytes, tx checksumming: ko]
[    3.424033] Intel(R) Wireless WiFi driver for Linux
[    3.424054] Copyright(c) 2003- 2015 Intel Corporation
[    3.424353] iwlwifi 0000:05:00.0: enabling device (0000 -> 0002)
[    3.426602] iwlwifi 0000:05:00.0: Direct firmware load for iwlwifi-7265D-29.ucode failed with error -2
[    3.426643] iwlwifi 0000:05:00.0: Direct firmware load for iwlwifi-7265D-28.ucode failed with error -2
[    3.426682] iwlwifi 0000:05:00.0: Direct firmware load for iwlwifi-7265D-27.ucode failed with error -2
[    3.426719] iwlwifi 0000:05:00.0: Direct firmware load for iwlwifi-7265D-26.ucode failed with error -2
[    3.426757] iwlwifi 0000:05:00.0: Direct firmware load for iwlwifi-7265D-25.ucode failed with error -2
[    3.426795] iwlwifi 0000:05:00.0: Direct firmware load for iwlwifi-7265D-24.ucode failed with error -2
[    3.426835] iwlwifi 0000:05:00.0: Direct firmware load for iwlwifi-7265D-23.ucode failed with error -2
[    3.426872] iwlwifi 0000:05:00.0: Direct firmware load for iwlwifi-7265D-22.ucode failed with error -2
[    3.426900] iwlwifi 0000:05:00.0: no suitable firmware found!
[    3.426917] iwlwifi 0000:05:00.0: minimum version required: iwlwifi-7265D-22
[    3.426937] iwlwifi 0000:05:00.0: maximum version supported: iwlwifi-7265D-29
[    3.426958] iwlwifi 0000:05:00.0: check git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git

错误代码是-2,意思是no such file or directory,原因应该是找不到firmware。
使用modinfo查看模块iwlwifi,进一步确认错误:

# modinfo  iwlwifi | grep iwlwifi-7265
firmware:       iwlwifi-7265D-29.ucode
firmware:       iwlwifi-7265-17.ucode

确认其需要iwlwifi-7265D-29.ucode。

再确认内核配置:

Device Drivers  --->
            Generic Driver Options  --->
                Firmware loader --->
 
                    -*- Firmware loading facility
                    () Build named firmware blobs into the kernel binary
                    (/lib64/firmware) Firmware blobs root directory
                    [ ] Enable the firmware sysfs fallback mechanism

可以看到firmware的root目录在/lib64/firmware/目录下。
但在/lib64/firmware/目录下,能找到这个文件:

# ls /lib64/firmware/iwlwifi-7265D-29.ucode
/lib64/firmware/iwlwifi-7265D-29.ucode

这就很奇怪了,目录下有这个文件,但却没有找到。
无法找到原因,只能使用暂时的解决办法。
修改内核配置,把firmware直接build进内核:

Device Drivers  --->
            Generic Driver Options  --->
                Firmware loader --->
 
                    -*- Firmware loading facility
                    (iwlwifi-7265D-29.ucode) Build named firmware blobs into the kernel binary
                    (/lib64/firmware) Firmware blobs root directory
                    [ ] Enable the firmware sysfs fallback mechanism

构建内核并重启后,网卡成功识别,至此问题解决。
但是还是无法知道,无法正确加载的原因。
后续知道原因后会继续更新,知道原因的朋友麻烦也告诉我一下。

pytorch模型转libtorch调用

最近项目上线,需要把pytorch的模型,转成用libtorch进行调用。
踩了不少坑,特此记录一下。

1、迭代无法使用,报错如下:
TracerWarning: Iterating over a tensor might cause the trace to be incorrect. Passing a tensor of different shape won't change the number of iterations executed (and might lead to errors or silently give incorrect results).
一般是直接使用数据导致:

for d in data:
   pass

改成如下:

for i in data.shape[0]:
    pass

2、tensor类型转python类型报错报错,例如:
TracerWarning: Converting a tensor to a Python boolean might cause the trace to be incorrect. We can't record the data flow of Python values, so this value will be treated as a constant in the future. This means that the trace might not generalize to other inputs!
再例如:
TracerWarning: Converting a tensor to a Python float might cause the trace to be incorrect. We can't record the data flow of Python values, so this value will be treated as a constant in the future. This means that the trace might not generalize to other inputs!

3、
TracerWarning: torch.tensor results are registered as constants in the trace. You can safely ignore this warning if you use this function to create tensors out of constant variables that would be the same every time you call this function. In any other case, this might cause the trace to be incorrect.

4、多个返回值,报错如下:
Encountering a list at the output of the tracer might cause the trace to be incorrect, this is only valid if the container structure does not change based on the module's inputs. Consider using a constant container instead (e.g. for list, use a tupleinstead. fordict, use a NamedTuple instead). If you absolutely need this and know the side effects, pass strict=False to trace() to allow this behavior.
根据提示,把list改成tuple,把dict改成NamedTuple即可。

pcieport报错分析和解决

新装好的gentoo,使用dmesg总是报pcieport错误
$ dmesg

kernel: pcieport 0000:00:1c.5: AER: Multiple Corrected error received: 0000:00:1c.5
kernel: pcieport 0000:00:1c.5: AER: PCIe Bus Error: severity=Corrected, type=Data Link Layer, (Transmitter ID)
kernel: pcieport 0000:00:1c.5: AER: device [8086:a295] error status/mask=00001000/00002000
kernel: pcieport 0000:00:1c.5: AER: [12] Timeout

可以看出,是00:1c.5[8086:a295]这个设备有问题。

1. 确认出错设备

$ lspci -s 00:1c.5 -v

00:1c.5 PCI bridge: Intel Corporation 200 Series PCH PCI Express Root Port #6 (rev f0) (prog-if 00 [Normal decode])
Flags: bus master, fast devsel, latency 0, IRQ 122
Bus: primary=00, secondary=03, subordinate=03, sec-latency=0
I/O behind bridge: [disabled]
Memory behind bridge: df200000-df3fffff [size=2M]
Prefetchable memory behind bridge: [disabled]
Capabilities:
Kernel driver in use: pcieport

是一个PCI bridge。

2. 进一步确认PCI连接的设备

$ lspci -t

-[0000:00]-+-00.0
+-01.0-[01]--+-00.0
| -00.1
+-08.0
+-14.0
+-14.2
+-15.0
+-15.1
+-16.0
+-17.0
+-1c.0-[02]----00.0
+-1c.5-[03]----00.0
+-1e.0
+-1f.0
+-1f.2
+-1f.3
-1f.4

可以看到1c.5上连接的是03:00.0。
$ lspci -nn |grep 03:00.0

03:00.0 Network controller [0280]: Qualcomm Atheros QCA9377 802.11ac Wireless Network Adapter [168c:0042] (rev 31)

最终确认到是无线网卡出现问题

3. 确认设备问题

google后,看到有地方说,是驱动原因。检查一下:
$ sudo lshw -C network

*-network
description: Ethernet interface
product: RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller
vendor: Realtek Semiconductor Co., Ltd.
physical id: 0
bus info: pci@0000:02:00.0
logical name: enp2s0
version: 15
serial: 8c:ec:4b:bb:1d:89
size: 1Gbit/s
capacity: 1Gbit/s
width: 64 bits
clock: 33MHz
capabilities: pm msi pciexpress msix bus_master cap_list ethernet physical tp mii 10bt 10bt-fd 100bt 100bt-fd 1000bt-fd autonegotiation
configuration: autonegotiation=on broadcast=yes driver=r8169 driverversion=5.12.7-gentoo duplex=full firmware=rtl8168h-2_0.0.2 02/26/15 ip=10.10.27.45 latency=0 link=yes multicast=yes port=twisted pair speed=1Gbit/s
resources: irq:16 ioport:d000(size=256) memory:df404000-df404fff memory:df400000-df403fff
*-network
description: Wireless interface
product: QCA9377 802.11ac Wireless Network Adapter
vendor: Qualcomm Atheros
physical id: 0
bus info: pci@0000:03:00.0
logical name: wlp3s0
version: 31
serial: 6a:dd:1a:01:81:b8
width: 64 bits
clock: 33MHz
capabilities: pm msi pciexpress bus_master cap_list ethernet physical wireless
configuration: broadcast=yes driver=ath10k_pci driverversion=5.12.7-gentoo firmware=WLAN.TF.2.1-00021-QCARMSWP-1 latency=0 link=no multicast=yes wireless=IEEE 802.11
resources: irq:127 memory:df200000-df3fffff

驱动是ath10k_pci,从以下网址确认了,使用的驱动并没有出错:
https://linux-hardware.org/?id=pci:168c-0042-17aa-0901
https://wireless.wiki.kernel.org/en/users/drivers/ath10k

4. 解决方法

继续google,看到说可能是节电功能出现问题。
尝试关闭PCIe的节电功能(PCIe Active State Power Management),虽然这样可能导致耗电增加。
修改/etc/default/grub文件,在GRUB_CMDLINE_LINUX_DEFAULT处添加pcie_aspm=off,例如:
GRUB_CMDLINE_LINUX_DEFAULT="pcie_aspm=off"

然后更新grub:
$ sudo grub-mkconfig -o /boot/grub/grub.cfg

重启后,问题解决。

WebRTC编译

最近项目需要用到WebRTC,发现之前做过的都忘记得差不多了。好记性不如烂笔头,还是记录一下,防止下次又忘记了。

1、第一步先安装depot_tools,并配置代理。
# git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
然后添加depot_tools文件夹到PATH变量,编辑home目录下的.bashrc文件,然后export变量:

# cat /home/${YOUR_USER_NAME}/.bashrc
...
export DEPOT_TOOLS_UPDATE=0 #可选,防止每次使用depot_tools都会升级
export NO_AUTH_BOTO_CONFIG=/home/${YOUR_USER_NAME}/.boto.cfg  #可选,使用boto时调用代理
export PATH=/home/${YOUR_USER_NAME}/depot_tools:$PATH #必选,添加depot_tools文件夹到PATH环境变量
...

# source /home/${YOUR_USER_NAME}/.bashrc

因为某些原因,后面可能无法下载成功,需要配置代理。
boto代理如下:

# cat /home/${YOUR_USER_NAME}/.boto.cfg
[Boto]
proxy=${YOUR_PROXY_SEVER_ADDRESS}
proxy_port=${YOUR_PROXY_SEVER_PORT}

除了boto代理外,还需要配置git代理:

# git config --global https.proxy http://${YOUR_PROXY_SEVER_ADDRESS}:${YOUR_PROXY_SEVER_PORT}
# git config --global https.proxy https://${YOUR_PROXY_SEVER_ADDRESS}:${YOUR_PROXY_SEVER_PORT}

最后还要配置http和https的代理。

export http_proxy=http://${YOUR_PROXY_SEVER_ADDRESS}:${YOUR_PROXY_SEVER_PORT}
export https_proxy=http://${YOUR_PROXY_SEVER_ADDRESS}:${YOUR_PROXY_SEVER_PORT}

注意这一步的代理是临时性的,如果要一直用,也可添加到用户目录下的.bashrc文件。方法和前面的一致。

2、下载源码。这一步依赖于网速,因为到这篇文章发布的时候为止,源码目录就占用19G了。

# mkdir webrtc-checkout
# cd webrtc-checkout
# fetch --nohooks webrtc
# gclient sync

如果下载失败,可以重复执行gclient sync命令。直至最后所有数据同步成功。

3、编译代码前,先看看默认的编译参数。
# gn args out/Default
这里直接退出文本编辑器即可。
# gn args out/Default --list
执行上面的命令就能看到所有的编译参数了。此处不详细展开参数说明。

4、编译Release版本的WebRTC。

# gn gen out/Release --args='is_debug=false rtc_use_h264=true strip_debug_info=true'
# gn args out/Release --list

确认参数后,就可以直接编译了

# ninja -C out/Release

编译好后,就可以获得out/Release/obj/libwebrtc.a文件进行后续开发了。
另外,在out/Release目录下,还有一些例子可以先跑一下,此处不展开。
感兴趣的,可以访问webrtc的官网:
https://webrtc.github.io/webrtc-org/native-code/development/

5、错误集锦。

  1. 如果提示以下错误:
# gn gen out/Release --args='is_debug=false rtc_use_h264=true strip_debug_info=true'
ERROR at //build/config/sysroot.gni:64:7: Assertion failed.
      assert(
      ^-----
Missing sysroot (//build/linux/debian_bullseye_amd64-sysroot). To fix, run: build/linux/sysroot_scripts/install-sysroot.py --arch=amd64
See //build/config/sysroot.gni:65:11: 
          exec_script("//build/dir_exists.py",
          ^-----------------------------------
This is where it was set.
See //build/config/linux/pkg_config.gni:5:1: whence it was imported.
import("//build/config/sysroot.gni")
^----------------------------------
See //BUILD.gn:24:1: whence it was imported.
import("//build/config/linux/pkg_config.gni")

是因为缺少了sysroot,按照提示运行以下命令即可。
# build/linux/sysroot_scripts/install-sysroot.py --arch=amd64

  1. 有文件一直下载失败,例如
# glicent sync
Syncing projects: 100% (43/43), done.                                                   
Running hooks:  66% (18/27) clang_format_linux    
________ running 'python3 src/third_party/depot_tools/download_from_google_storage.py --no_resume --platform=linux* --no_auth --bucket chromium-clang-format -s src/buildtools/linux64/clang-format.sha1' in '/home/data/webrtc-checkout'
0> Downloading src/buildtools/linux64/clang-format@dd736afb28430c9782750fc0fd5f0ed497399263...
0> Failed to fetch file gs://chromium-clang-format/dd736afb28430c9782750fc0fd5f0ed497399263 for src/buildtools/linux64/clang-format, skipping. [Err: INFO 0709 12:40:18.394795 retry_util.py] Retrying request, attempt #1...

重复多次之后,还是无法从gs://chromium-clang-format/dd736afb28430c9782750fc0fd5f0ed497399263这个地址下载成功。
从出错信息上看,应该是把dd736afb28430c9782750fc0fd5f0ed497399263放到src/buildtools/linux64/,并重命名为clang-format
碰到这种情况,可以换成http下载,例如上面的地址,可以换成https://storage.googleapis.com/chromium-clang-format/dd736afb28430c9782750fc0fd5f0ed497399263。下载成功后,放到对应目录即可。

GDB打印STL容器中的内容

一般情况下,使用GDB调试C++,会无法显示STL容器的内容,这给调试带来很大麻烦。
在GDB 7.0后,可以使用GCC提供的python脚本,对STL容器内容进行显示。
一般的Linux发行版,脚本默认跟随GCC提供。
需要先找到脚本路径:

# find /usr/share -name "printers.py"
/usr/share/gcc-data/x86_64-pc-linux-gnu/8.3.0/python/libstdcxx/v6/printers.py

注意,发行版不一样,路径可能不同。

再在用户目录下,创建.gdbinit文件,添加内容,即可显示:

python
import sys
sys.path.insert(0, '/usr/share/gcc-data/x86_64-pc-linux-gnu/8.3.0/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end

此处注意,必须是前面找到的python脚本路径!

之后,就可以使用GDB轻松显示STL容器的内容了。
同时,vscode也可以正常显示。

win10下使用vscode attach调试cl.exe编译的dll

### 新版的已经很简单了,把旧版教程删除了

在win10下,普通的c++程序比较好调试。
但是,如果想要attach调试某个进程加载的dll,特别是这个dll还是用cl.exe编译的情况下,就比较复杂了。

步骤如下:
1、安装system Installer版本的vscode,不能使用User Installer版本的,否则执行第2步后,vscode无法启动
2、找到vscode的安装路径,右键Code.exe,选择属性->兼容性,勾选“以管理员身份运行此程序”
3、生成launch.json,例子可参考下面的,注意修改processId即可

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "debug",
            "type": "cppvsdbg",
            "request": "attach",
            "processId": "${command:pickProcess}"
        }
    ]
}

4、按F5就会列出当前运行的进程,找到需要attach的程序即可,

ubuntu 18.04下编译windows版本的VLC 3.0.8

第一次尝试在linux下编译windows的程序,踩了不少坑,特此记录一下。

VLC本身比较难编译,看了很多中文的教程,都吐槽说官方教程不靠谱,但我编译到最后,发现还是官方教程最靠谱。照着官方教程做下来,坑是最少的。
此处附上官方教程地址:
https://wiki.videolan.org/Win32Compile/

一开始使用的是ubuntu 16.04,发现很多依赖包版本太老,就换成了18.04。
安装的是Mingw-w64环境,编译64版本。
这里注意官方教程有一句话:

NB: you need mingw-w64 version 5.0.1 to compile it.

而18.04默认安装的mingw是5.0.3,但对应的gcc7.3,编译到后面会出现问题,建议先升级到19.04的6.0.0。
具体升级方法看后文。
如果不想浪费时间,一定要先升级!

此处可能把ubuntu换成19.04更好。但因为一开始不知道,ubuntu还是使用18.04,只是升级了mingw到19.04的版本。

首先编译第三方库,注意因为编译的是3.0.8版本的VLC,必须使用Manually built方式,不能使用Prebuilt方式。
一路安装下来,如果提示缺少包,直接apt安装即可。大部分依赖都可以用这种方式安装。
如果遇到提示安装meson的版本太低,则可以卸载apt安装的版本,然后用pip3安装即可。

一个比较坑的问题,是在编译gcrypt的时候,提示syntax error:

/bin/bash ../libtool --mode=compile --tag=RC x86_64-w64-mingw32-windres -DHAVE_CONFIG_H -I. -I../../src -I..     -i "versioninfo.rc" -o "versioninfo.lo"
libtool: compile:  x86_64-w64-mingw32-windres -DHAVE_CONFIG_H -I. -I../../src -I.. -i versioninfo.rc  -o .libs/versioninfo.o
x86_64-w64-mingw32-windres: versioninfo.rc.in:21: syntax error
Makefile:1240: recipe for target 'versioninfo.lo' failed
make[2]: *** [versioninfo.lo] Error 1

原因是configure.ac里,写死了一些git的操作。而vlc编译的源码,是tar包,没有git的相关信息,导致编译失败。具体可以参考https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=814954

--- a/configure.ac
+++ b/configure.ac
@@ -39,7 +39,7 @@
 m4_define(mym4_version,
           [mym4_version_major.mym4_version_minor.mym4_version_micro])
 m4_define([mym4_revision],
-          m4_esyscmd([git rev-parse --short HEAD | tr -d '\n\r']))
+          m4_esyscmd([printf %x $(wc -l < debian/changelog)]))
 m4_define([mym4_revision_dec],
           m4_esyscmd_s([echo $((0x$(echo ]mym4_revision[|head -c 4)))]))
 m4_define([mym4_betastring],

修改configure.ac,跳过git操作即可。

另一个比较坑的问题,是在编译glew的时候,提示找不到依赖库:

x86_64-w64-mingw32-ld -o lib/glew32.dll src/glew.o -L/mingw/lib -lglu32 -lopengl32 -lgdi32 -luser32 -lkernel32
x86_64-w64-mingw32-ld: cannot find -lglu32
x86_64-w64-mingw32-ld: cannot find -lopengl32
x86_64-w64-mingw32-ld: cannot find -lgdi32
x86_64-w64-mingw32-ld: cannot find -luser32
x86_64-w64-mingw32-ld: cannot find -lkernel32
Makefile:101: recipe for target 'lib/glew32.dll' failed

查了很久才发现,是“-L/mingw/lib”的问题。在windows下用mingw编译,路径就是“/mingw/lib”,但是,在linux下编译,路径就不是这个了。
首先使用x86_64-w64-mingw32-ld命令,通过SEARCH_DIR确定mingw的lib路径:

$ x86_64-w64-mingw32-ld --verbose | grep SEARCH_DIR | tr -s ' ;' \\012
SEARCH_DIR("=/usr/local/lib/x86_64-linux-gnu")
SEARCH_DIR("=/lib/x86_64-linux-gnu")
SEARCH_DIR("=/usr/lib/x86_64-linux-gnu")
SEARCH_DIR("=/usr/local/lib")
SEARCH_DIR("=/lib")
SEARCH_DIR("=/usr/lib")
SEARCH_DIR("=/usr/x86_64-w64-mingw32/lib")

可以看到,路径是“/usr/x86_64-w64-mingw32/lib”。
查到路径后,修改glew/config/Makefile.mingw文件,把里面的“/mingw/lib”修改成“/usr/x86_64-w64-mingw32/lib”,就可以继续编译了。

编译完第三方库,按照教程,继续编译VLC。
但一部分插件会无法编译,错误如下:

CXXLD libdcp_plugin.la
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_Z35_txnal_cow_string_C1_for_exceptionsPvPKcS_+0x2c): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_RU1'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_Z35_txnal_cow_string_C1_for_exceptionsPvPKcS_+0x39): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `transaction clone for operator new[](unsigned long long)'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_Z35_txnal_cow_string_C1_for_exceptionsPvPKcS_+0x5d): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_memcpyRtWn'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_Z23_txnal_cow_string_c_strPKv+0x1): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_RU8'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_Z23_txnal_sso_string_c_strPKv+0x1): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_RU8'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_Z20_txnal_cow_string_D1Pv+0x5): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_RU8'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_Z20_txnal_cow_string_D1Pv+0x1e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_addUserCommitAction'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_ZGTtNSt11logic_errorC1EPKc+0x2e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_memcpyRnWt'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_ZGTtNSt11logic_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+0x2e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_memcpyRnWt'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_ZGTtNSt11logic_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE+0x36): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ITM_RU8'
/usr/lib/gcc/x86_64-w64-mingw32/7.3-win32/libstdc++.a(cow-stdexcept.o):(.text$_ZGTtNSt11logic_errorD0Ev+0x1a): additional relocation overflows omitted from the output
collect2: error: ld returned 1 exit status
Makefile:13212: recipe for target 'libdcp_plugin.la' failed

这是一个存在于6和7版本gcc的bug,gcc8已经修复。
详细信息可以查看论坛:https://forum.videolan.org/viewtopic.php?t=144693
而18.04安装的gcc版本是7.3,所以会碰到这个bug。
修复方法是升级gcc,或者修改libstdc++的os_defines.h文件,并重新编译工具链。
这里我采用的是升级gcc7到gcc8的方法。
卸载所有mingw的包,直接下载安装ubuntu 19.04的mingw安装包即可。
可以直接使用包名去搜索,很容易就能搜索到下载地址。此处不提供下载地址。
注意mingw的gcc包换了,那对应的mingw包也要换,不然头文件会冲突。

gcc-mingw-w64-base_8.3.0-6ubuntu1+21.1build2_amd64.deb
gcc-mingw-w64-x86-64_8.3.0-6ubuntu1+21.1build2_amd64.deb
g++-mingw-w64-x86-64_8.3.0-6ubuntu1+21.1build2_amd64.deb
mingw-w64-common_6.0.0-3_all.deb
mingw-w64-tools_6.0.0-3_amd64.deb
mingw-w64-x86-64-dev_6.0.0-3_all.deb

替换上述6个包后,必须从头开始,从第三方库开始编译,不然也会出现问题。T_T...
如果还需要编译32位的vlc,则还需要安装以下几个包:

gcc-mingw-w64-i686_8.3.0-6ubuntu1+21.1build2_amd64.deb
g++-mingw-w64-i686_8.3.0-6ubuntu1+21.1build2_amd64.deb
mingw-w64-i686-dev_6.0.0-3_all.deb

安装方法是:

$ sudo dpkg -i *.deb
$ sudo apt install -f

另外,在编译的时候,如果系统安装了protobuf,则需要检查是不是3.1.0版本,不然会出现以下问题:

make[4]: Entering directory 'vlc-3.0.8-win64-gcc8.3/win32/modules'
  CXX      stream_out/chromecast/libstream_out_chromecast_plugin_la-cast.lo
In file included from vlc-3.0.8-win64-gcc8.3/contrib/x86_64-w64-mingw32/include/google/protobuf/stubs/common.h:40,
                 from stream_out/chromecast/cast_channel.pb.h:9,
                 from ../../extras/package/win32/../../../modules/stream_out/chromecast/chromecast.h:45,
                 from ../../extras/package/win32/../../../modules/stream_out/chromecast/cast.cpp:33:
vlc-3.0.8-win64-gcc8.3/contrib/x86_64-w64-mingw32/include/google/protobuf/stubs/port.h:56:7: warning: "_MSC_VER" is not defined, evaluates to 0 [-Wundef]
   #if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
       ^~~~~~~~
In file included from ../../extras/package/win32/../../../modules/stream_out/chromecast/chromecast.h:45,
                 from ../../extras/package/win32/../../../modules/stream_out/chromecast/cast.cpp:33:
stream_out/chromecast/cast_channel.pb.h:17:2: error: #error This file was generated by an older version of protoc which is
 #error This file was generated by an older version of protoc which is
  ^~~~~
stream_out/chromecast/cast_channel.pb.h:18:2: error: #error incompatible with your Protocol Buffer headers. Please
 #error incompatible with your Protocol Buffer headers.  Please
  ^~~~~
stream_out/chromecast/cast_channel.pb.h:19:2: error: #error regenerate this file with a newer version of protoc.
 #error regenerate this file with a newer version of protoc.
  ^~~~~
Makefile:25318: recipe for target 'stream_out/chromecast/libstream_out_chromecast_plugin_la-cast.lo' failed

就是vlc需要用到的protobuf版本和系统安装的版本不一致。
运行命令可以检查是否安装了其他版本的protobuf:

$ locate protobuf
$ dpkg -l |grep protobuf

检查后,系统的确安装了protobuf,需要卸载:
sudo apt autoremove libprotoc10 libprotobuf10 protobuf-compiler
注意这里会把protobuf-compiler卸载掉,会导致第三方库里的projectM无法编译。
需要自己编译安装protobuf的3.1.0版本,简单的方法是:

$ cd protobuf-3.1.0
$ ./autogen.sh
$ ./configure --prefix=/usr
$ make
$ make check
$ sudo make install

安装好之后,继续需要从头开始,从第三方库开始编译T_T...

一切顺利的话,vlc就编译好了。
然后打包:
$ make package-win-common
因为我的源码是直接下载的压缩包,里面没有hrtfs目录下的文件,所以不能打包。
从git下载后,放到对应目录,再运行打包命令就可以了。
打包完成后,里面多了一个目录vlc-3.0.8,比起直接安装的vlc,里面的dll都带了调试信息,也多了一个sdk的目录,里面包括头文件和lib文件。
这是用来二次开发的,如果不需要,可以运行其他打包命令。

至此,vlc算是编译完成了。
花了2天的时间才搞定,整体来说难度不小。
主要还是要沉下心来,遇到一个问题解决一个,才能编译成功。

后续还要进行二次开发,有问题再更新把。

CentOS7安装新版本GCC

本文只是记录,没啥价值,可不看。
先安装源。

# yum install -y centos-release-scl
# yum search devtoolset

找到合适的版本后,可以直接安装,例如安装11。

# yum install devtoolset-11-gcc*

安装好后,启用即可。

# scl enable devtoolset-11 bash
# gcc --version

或者添加source命令到~/.bashrc的最后。

# vim ~/.bashrc
......
source /opt/rh/devtoolset-11/enable

LLDB打印数组

最近使用vscode开发c/c++,从原来使用微软的c/c++扩展,改成了clangd。
而debug用的gdb,也改成了CodeLLDB自带的调试器。

平时在gdb下,打印数组,直接输入:
array_name[0]@array_len
这个在lldb里不能用了,必须切换到调试控制台,并输入:
parray `array_len` array_name
如果想输出十进制,则输入:
parray/d `array_len` array_name

Gentoo更新某个库并更新依赖这个库的所有包

在最近升级gentoo的时候,因为某个包不能使用GCC10,就切换到了GCC11,然后继续编译。
更新到最后,发现某个包又需要依赖GCC10,则又从GCC11切回了GCC10。
因为这两次切换,中间都编译了QT和依赖QT的库。
然后,问题就出现了。
部分QT库用的GCC11,部分用的GCC10。
就导致后面一堆包编译无法通过。
因为无法确定,到底哪些包用的GCC10,哪些包用的GCC11,只能对这些这些包全部重新编译。
好在,Gentoo已经考虑到了这个情况,一条命令即可:
revdep-rebuild --library 'libQt5Core.so.5' --
等待一段时间,编译完成后,问题消失。

使用Emscripten编译ORB_SLAM3实现Web AR

ORB_SLAM3是一个目前比较流行的SLAM开源项目。
目前国内很多公司或者高校,都会基于此项目,实现相关的产品。
但是,一般产品都是运行在服务器,或者是手机端app,Web端几乎没有。
因此,为了试验ORB_SLAM3运行在Web端是否可行,就有了本篇blog。
如果对于Emscripten和WebAssembly还不了解的话,可以参考Mozilla的教程,自己先熟悉一下。
废话不多说,我们开始吧。

- 编译依赖

注意,为了后续方便,也最好找一个目录,安装编译好后的库文件,这里假设使用"/Path/usr"目录。
当然,也可以安装到$EMSCRIPTEN/system目录。看个人喜好。
做过嵌入式开发的应该比较熟悉。
另外,还要注意,因为ORB_SLAM3需要用到线程,而Emscripten的64位对线程支持还不太好。
而且考虑到安全问题,手机上浏览器对线程的支持(移除了AtomicsSharedArrayBuffer支持)都比较一般,所以后续可能还要去掉线程部分(大改)。目前手机上是没跑成功的。

1. 编译boost
boost官网下载压缩包并解压,当前最新版本是1.77.0。
注意这里不能使用太老的版本,原因是我们后续要指定编译使用的toolset为Emscripten,而太老的版本可能不支持。
其它步骤和普通编译区别不大。

$ ./bootstrap.sh --prefix=/Path/usr --with-libraries=system,serialization
$ ./b2 install toolset=emscripten link=static variant=release threading=single runtime-link=static system serialization
编译中...
emscripten.archive bin.v2/libs/system/build/emscripten-2.0.28/release/link-static/visibility-hidden/libboost_system.bc
编译中...
emscripten.archive bin.v2/libs/serialization/build/emscripten-2.0.28/release/link-static/visibility-hidden/libboost_serialization.bc
编译中...

从输出可以看到,编译了libboost_serialization.bc和libboost_system.bc。
因为我们只需要用到system和serialization两个component,为了节省时间,其它就不编译了。
注意,为了避免多线程产生问题,此处指定了单线程编译。
另外,有兴趣的还可以通过emscripten-ports使用boost,此处不详细展开。
最后,可以看到,include和lib等文件,已经被安装到了/Path/usr目录下。

2. 编译OpenCV
其实OpenCV已经有编译好的js文件了,但因为我们要用到的是静态库,所以此处还是自己编译一份。
从opencv官网下载压缩包并解压,此处使用4.5.2版本。
新版本已经自带编译脚本,指定一下emscripten的路径(一般是在/XXX/XXX/emsdk/upstream/emscripten)即可编译。
这里我们并没有使用opencv_contrib,因为用不上。有需要的,可以修改编译脚本并编译。
编译之前也要修改安装的文件夹,修改platforms/js/build_js.py里的cmake命令参数,加上-DCMAKE_INSTALL_PREFIX=/Path/usr。

$ cd opencv-4.5.2
$ mkdir build
$ cd build
$ python ../platforms/js/build_js.py --emscripten_dir /XXX/XXX/emsdk/upstream/emscripten  --build_wasm .
$ emmake make install
编译中...
=====
===== Build finished
=====
OpenCV.js location: /xxx/xxx/opencv-4.5.2/build/bin/opencv.js

可以看到,opencv.js已经编译完成。
同时,所有库文件也自动安装到了/Path目录下。

3. 编译Eigen3
Eigen官网下载源码并解压,当前版本是3.4.0。

$ cd eigen-3.4.0
$ mkdir build
$ cd build
$ emcmake cmake .. -DCMAKE_INSTALL_PREFIX=/Path/usr
$ emmake make && emmake make install

这样就装到了/Path/usr目录了。
注意这里多了一个emcmake,只要把它用在cmake前面,就会自动给cmake加上所需的参数,方便编译。

4. 编译OpenSSL
直接编译安装即可,这里使用1.1.0h版本。

$ cd openssl-1.1.0h
$ emconfigure ./Configure linux-generic32 --prefix=/Path/usr
$ sed -i 's|^CROSS_COMPILE.*$|CROSS_COMPILE=|g' Makefile
$ emmake make -j 12 build_generated libssl.a libcrypto.a
$ cp -R include/openssl /Path/usr/include
$ cp libcrypto.a libssl.a /Path/usr/lib

5. 编译Pangolin
不编译
因为用不上,但后续要删除ORB_SLAM3关于Pangolin的所有代码。

5. 编译ORB_SLAM3
因为步骤太多,此处不展示修改后的代码,只写下步骤:

  • 删除所有显示相关的代码,例如Pangolin和OpenGL还有OpenCV的highgui
  • 修改#include <stdint-gcc.h>成#include <stdint.h>
  • 把DBoW2和g2o改成静态编译
  • 把带tr1的头文件修改成不带tr1的,例如#include <tr1/unordered_map>改成#include <unordered_map>
  • build.sh文件里,所有cmake前加emcmake,所有make前加emmake,并添加对应的环境变量,例如前面编译的库的路径,也要加上去

然后直接运行build.sh即可在build目录得到相对应的libORB_SLAM3.a文件。
最后,编写对应的调用函数,并编译成wasm加js文件即可。
和其它的库调用没区别,此处不展开。

这是效果图,PC上浏览器的效果还是不错的。
ORB_SLAM3

SELinux下Nginx的一些问题解决方法

最近装了Centos7,默认开启的SELinux。
使用过程中,发现了一些问题,如下:

一、无法使用proxy_pass转发请求。

# getsebool httpd_can_network_connect
httpd_can_network_connect --> off

发现是httpd_can_network_connect这个的值导致的,修改之:

# setsebool httpd_can_network_connect 1 -P
# getsebool httpd_can_network_connect
httpd_can_network_connect --> on

就可以顺利转发了。

二、只能监听80和443端口,其它端口无法监听。如果监听了其它端口,则报错

nginx[13009]: nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx[13009]: nginx: [emerg] bind() to 0.0.0.0:8081 failed (13: Permission denied)

安装semanage,查看http的端口

# yum install policycoreutils-python -y
# semanage port -l |grep http_port_t
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t            tcp      5988

打开所需的端口,例如18554:

# semanage port -a -t http_port_t  -p tcp 18554
# semanage port -l |grep http_port_t
http_port_t                    tcp      18554, 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t            tcp      5988

可以看到,18554端口已经加进去了。

如果提示已定义端口,例如:
ValueError: 已定义端口 tcp/8000
则修改命令为:

# semanage port -m -t http_port_t  -p tcp 8000
http_port_t                    tcp      8000,80, 81, 443, 488, 8008, 8009, 8443, 9000

此时,重启nginx,就可以监听其它端口了。

linux下Cherry MX Board 3.0 S键盘一直发248的问题

win下安装下载CHERRY Utility Software,然后更新最新固件后也可解决。
此文已失效!!!

最近买了个Cherry MX Board 3.0 S键盘,在windows下用得好好的,但是linux下,操作各种不正常。
检查后发现,键盘一直在发248这个keycode???

$ xev
KeyRelease event, serial 40, synthetic NO, window 0x800001,
    root 0x42a, subw 0x0, time 501467, (-365,-136), root:(506,315),
    state 0x4, keycode 248 (keysym 0x63, c), same_screen YES,
    XLookupString gives 1 bytes: (03) ""
    XFilterEvent returns: False

查了一下,不止我有这个问题。
最后通过添加udev的rule解决了。

先查找键盘的Vendor和Product

$ lsusb
Bus 003 Device 002: ID 046a:0077 Cherry GmbH Mechanical Keyboard

可以看到是046a:0077。
添加 /etc/udev/rules.d/cherry-keyboard.rule文件,内容如下:
ACTION=="add", SUBSYSTEM=="input", ATTRS{idVendor}=="046a", ATTRS{idProduct}=="0077", ATTR{capabilities/ev}=="10001f", ATTR{inhibited}="1"
重启后解决,键盘一切正常了。

最近买了个Cherry MX Board 3.0 S键盘,在windows下用得好好的,但是linux下,操作各种不正常。
检查后发现,键盘一直在发248这个keycode???

$ xev
KeyRelease event, serial 40, synthetic NO, window 0x800001,
    root 0x42a, subw 0x0, time 501467, (-365,-136), root:(506,315),
    state 0x4, keycode 248 (keysym 0x63, c), same_screen YES,
    XLookupString gives 1 bytes: (03) ""
    XFilterEvent returns: False

查了一下,不止我有这个问题。
最后通过添加udev的rule解决了。

先查找键盘的Vendor和Product

$ lsusb
Bus 003 Device 002: ID 046a:0077 Cherry GmbH Mechanical Keyboard

可以看到是046a:0077。
添加 /etc/udev/rules.d/cherry-keyboard.rule文件,内容如下:
ACTION=="add", SUBSYSTEM=="input", ATTRS{idVendor}=="046a", ATTRS{idProduct}=="0077", ATTR{capabilities/ev}=="10001f", ATTR{inhibited}="1"
重启后解决,键盘一切正常了。

-march=native造成的SIGILL illegal instruction

如果在linux下编译程序的时候,指定了-march=native,gcc会使用CPUID获取主机的cpu信息,并根据cpu所支持的指令集,对程序进行优化。
造成的后果就是,如果程序运行在其它机器,刚好CPU又不支持某个指令的时候,就会造成SIGILL illegal instruction(非法指令)。
解决问题的方法很简单,直接去掉这个参数即可。

记一次奇怪的启动X程序出错

一直在gentoo下使用kde5,最近突然出现一个奇怪的问题,启动程序总是出错:

Invalid MIT-MAGIC-COOKIE-1 keyqt.qpa.xcb: could not connect to display :0
qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: minimal, offscreen, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, xcb.

因为之前从X切换到了wayland,所以怀疑是wayland导致的问题。
把wayland的东西删掉,切换回X,还是出现同样的问题。

再检查,以为是在kde里,开启了特效的原因。
关闭特效,问题还是出现。

被这个问题搞懵了,这时留意到一个现象,每次连接wifi,才会出现这个问题。
想起之前为了连接wifi方便,安装了NetworkManager。
是不是这个原因呢?
重启,连接wifi,果然,问题马上重现。
并且,发现这时候,hostname改变了,从原来的localhost变成了其它的名字。

尝试固定主机名
root #hostnamectl set-hostname <HOSTNAME>
果然问题消失了。
但为什么会导致这个问题呢?
翻查了gentoo的wiki:https://wiki.gentoo.org/wiki/NetworkManager
发现原来NetworkManager连上wifi后,如果你的主机名是localhost等其它默认名字,就会将主机名修改。
修改主机名后,会扰乱X的身份认证,导致再也无法启动任何程序。
可以通过xaut list查看认证信息:
$ xauth list

localhost/unix:18 MIT-MAGIC-COOKIE-1 4b24e44acce6ba8961cea417bf812ab9
localhost/unix:19 MIT-MAGIC-COOKIE-1 4b24e44acce6ba8961cea417bf812ab9
localhost/unix:20 MIT-MAGIC-COOKIE-1 dfb58d815903d96e5ddb53e86d16a429
localhost/unix:15 MIT-MAGIC-COOKIE-1 1e03efd46c325c3ddd562cb0f1e1e35d
localhost/unix:16 MIT-MAGIC-COOKIE-1 21a87eb1df1810c11dba97dc4345eb5c
localhost/unix:17 MIT-MAGIC-COOKIE-1 28f51a6c45e379cc1e826f35668af8d7
localhost/unix:14 MIT-MAGIC-COOKIE-1 6f3f1ebd6bbc8744e90b44f758c6a163
localhost/unix:12 MIT-MAGIC-COOKIE-1 e94484900fd094a06551c4d65fb79009
localhost/unix:13 MIT-MAGIC-COOKIE-1 ec6a926d8237c826a5353003b01a9707
localhost/unix:11 MIT-MAGIC-COOKIE-1 29ad1d10934823d0c578553018dd1ae2
localhost/unix:0 MIT-MAGIC-COOKIE-1 329aaf5433ef3892197121216d51d413
localhost/unix:10 MIT-MAGIC-COOKIE-1 e0f4fdc5eeb7909b52297787d5e05393
tunnel635996-pt.tunnel.tserv29.fmt1.ipv6.he.net/unix:0 MIT-MAGIC-COOKIE-1 ba04e68c5e1f1019f2526b120fa7567f
tunnel635996-pt.tunnel.tserv29.fmt1.ipv6.he.net/unix:10 MIT-MAGIC-COOKIE-1 51bc979adce58b8a603ec92496226406
tunnel635996-pt.tunnel.tserv29.fmt1.ipv6.he.net/unix:11 MIT-MAGIC-COOKIE-1 ad709ecf6d104d1e622c8cf9fbf4a349
localhost.localdomain/unix:12 MIT-MAGIC-COOKIE-1 b5eee9ab9f6037dec7f063b89bceda68
localhost.localdomain/unix:13 MIT-MAGIC-COOKIE-1 b915f78813c66b6488d4cee4ec3161e5
localhost.localdomain/unix:10 MIT-MAGIC-COOKIE-1 b2cd862cc1d1430475fe8dc680aacdc4
localhost.localdomain/unix:11 MIT-MAGIC-COOKIE-1 b5f39509353877883563f8f2d18d54c2
localhost.localdomain/unix:0 MIT-MAGIC-COOKIE-1 b30de5eccf5aba786198191d7d02cca4
office-computer/unix:0 MIT-MAGIC-COOKIE-1 0d090cc94106f273439a190125119e9e

另外,解决办法除了修改主机名之外,还可以在配置文件添加以下选项解决(未测试):

hostname-mode = none

多线程死锁的一种处理思路

最近碰到线上项目有时候莫名其妙死锁了,看日志看不出来原因。
还好,考虑到产品刚上线,目前还是采用的RelWithDebInfo的编译方式。
处理就比较简单了,安装gdb后,直接调试死锁的进程:

# gdb -p $process_id
(gdb)  info threads

随便找一个死锁的线程,确认是哪个mutex死锁后,打印这个mutex变量:

(gdb)  print $mutex

此时,mutex变量会显示owner信息,就是当前拥有锁的线程了。
剩下的问题就好办了,切换到那个线程,理清逻辑,就知道为啥死锁了。

另外,考虑到定位死锁位置耗时较长,可以直接让服务coredump:

# kill -6 $process_id

保存coredump的文件后,马上重启服务,降低服务中断造成的影响。
这里注意要打开保存coredump的选项,如果使用docker,其保存coredump的方法更复杂。
然后用coredump去进行前面的操作即可。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.