为什么选择C/C++内存检测工具AddressSanitizer?如何使用AddressSanitizer?

目录

1、C++程序中的内存问题

2、AddressSanitizer是什么?

3、AddressSanitizer内存检测原理简述

3.1、内存映射

3.2、插桩

4、为什么选择AddressSanitizer?

4.1、Valgrind介绍

4.2、AddressSanitizer在速度和内存方面为什么明显优于Valgrind

4.3、在很多实际项目中我们需要使用AddressSanitizer

5、无法使用Valgrind的具体项目实例

5.1、使用Valgrind检测导致CPU占满,无法进行检测

5.2、使用Valgrind检测导致程序运行过慢,无法进行检测

6、AddressSanitizer与其他内存工具的比较

7、如何使用AddressSanitizer?

7.1、升级gcc版本

7.2、如何配置使用AddressSanitizer进行内存检测

7.3、使用AddressSanitizer进行内存检测的实例

7.4、使用AddressSanitizer的注意事项

8、Windows平台高版本的Visual Studio也支持AddressSanitizer工具


VC++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/125529931C++软件分析工具从入门到精通案例集锦(专栏文章正在更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/131405795C/C++基础与进阶(专栏文章,持续更新中...)icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/category_11931267.html       C++程序中大部分问题都是内存问题,有些可以快速定位,有些则很难排查,通过日志打印及代码走读很难定位,并且有些难缠的问题只在客户的环境中才会出现(在公司内部测试环境中无法复现),处理起来非常头疼,把人搞的精疲力竭后可能还查不出来。今天给大家介绍来自Google的强大C/C++内存检测工具AddressSanitizer,它可以很好地解决实际应用环境中很多无法快速定位的内存问题。

1、C++程序中的内存问题

       在C++程序中,大部分程序运行异常都是内存问题引起的,内存问题也是最让C++程序员头疼的事情。常见的内存异常有空指针、野指针、线程栈溢出、内存越界(栈内存越界、堆内存越界和全局内存越界)、堆内存被破坏、内存泄漏、虚拟内存不足等,如下所示:

其中某些场景下的内存越界问题以及堆内存被破坏问题最为难查,特别是堆内存被破坏问题。一般堆内存被破坏会表现为,程序到处胡乱崩溃,一会崩在这里,一会崩在那里!因为堆内存被破坏,一会崩溃在new的地方,一会崩溃在delete的地方!

        关于C++软件异常及内存错误的详细说明,我就不在此赘述了,感兴趣的,可以去看看我之前写的文章:

C++软件异常分析概述icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/123991269引发C++程序内存错误的常见原因分析与总结icon-default.png?t=N7T8https://blog.csdn.net/chenlycly/article/details/128599525

2、AddressSanitizer是什么?

       AddressSanitizer(简称ASan)是google提供的一款面向C/C++语言的内存错误问题检查工具,它可以检测出堆溢出(Heap buffer overflow)、栈溢出(Stack buffer overflow)、全局变量越界(Global buffer overflow)、已释放内存使用(Use after free )、初始化顺序(Initialization order bugs)、内存泄漏(Use after free )等多个内存问题。

AddressSanitizer项目地址:AddressSanitizer · google/sanitizers Wiki · GitHub

参考文档页面:AddressSanitizerAlgorithm · google/sanitizers Wiki · GitHub

       AddressSanitizer相对于Valgrind要快很多,只拖慢程序两倍左右。它包括一个编译器instrumentation插桩模块和一个提供malloc/free替代项的运行时库。从gcc 4.8开始,AddressSanitizer成为gcc的一部分,使用时非常方便,只需要在编译时指定编译选项就可以了。gcc 4.8自带的AddressSanitizer还不完善,有明显的缺陷(比如当监测到任何一个error,它就会强制退出主程序,导致程序无法继续运行,再比如没有符号信息),最好使用gcc 4.9及以上版本。

AddressSanitizer原先只支持Linux,现在也可以在Windows上使用了。微软在Visual Studio 2019的16.9版本中引入了强大的内存分析工具AddressSanitizer。

3、AddressSanitizer内存检测原理简述

        AddressSanitizer主要由两部分组成:一个是静态插桩(Instrumentation)模块,将内存访问判断的逻辑直接插入在了二进制中,保证了检测逻辑的执行速度;另一部分则是运行时库(Run-time library),提供部分功能的开启、报错函数和 malloc/free/memcpy 等函数的ASan检测版本。

       instrument静态插桩模块,对栈上对象、全局对象、动态分配的对象分配redzone,以及针对这些内存做访问检测。

       runtime 运行时库提供了一些运行时的复杂的功能(比如poison/unpoison shadow memory),替换 malloc/free/memcpy/memset等实现,提供报错函数,针对每一次内存读写,编译器都会插入判断逻辑,判断地址是否被投毒(poisoned)。

该算法的思路是,如果要防住Buffer Overflow漏洞,只需要在每块内存区域右端(或两端,能防overflow和underflow)加一块区域(RedZone),使RedZone的区域的影子内存(Shadow Memory)设置为不可写即可。

3.1、内存映射

       AddressSanitizer保护的主要原理是对程序中的虚拟内存提供粗粒度的影子内存(每8个字节的内存对应一个字节的影子内存),为了减少overhead,采用了直接内存映射策略,所采用的具体策略如下:Shadow = (Mem >> 3) + offset。每8个字节的内存对应一个字节的影子内存:

​影子内存中每个字节存取一个数字k,如果k=0,则表示该影子内存对应的8个字节的内存都能访问,如果0<k<7,表示前k个字节可以访问,如果k为负数,不同的数字表示不同的错误(e.g. Stack buffer overflow, Heap buffer overflow)。

3.2、插桩

       为了防止buffer overflow,需要将原来分配的内存两边分配额外的内存Redzone,并将这两边的内存加锁,设为不能访问状态,这样可以有效的防止buffer overflow(但不能杜绝buffer overflow)。插桩的简化示意图如下:

​        以下是在栈中插桩的一个例子:

1)未插桩的代码:

void foo() 
{char a[8];// ...return;
}

2)插桩后的代码:

char redzone1[32]; // 32-byte aligned
char a[8];         // 32-byte aligned
char redzone2[24];
char redzone3[32]; // 32-byte aligned
int*shadow_base = MemToShadow(redzone1);
shadow_base[e] = oxffffffff;// poison redzone1
shadow_base[1] = oxffffffe0;// poison redzone2,unpoison 'a'
shadow_base[2] = oxffffffff;// poison redzone3
// ...
return;

       在动态运行库中将malloc/free函数进行了替换。在malloc函数中额外的分配了Redzone区域的内存,将与Redzone区域对应的影子内存加锁,主要的内存区域对应的影子内存不加锁。free函数将所有分配的内存区域加锁,并放到了隔离区域的队列中(保证在一定的时间内不会再被malloc函数分配),可检测Use after free类的问题。

4、为什么选择AddressSanitizer?

       Linux平台上常用的内存分析工具主要有Valgrind和AddressSanitizer,这两个工具在使用方式上有一定的区别。Valgrind不需要重新编译代码,可以直接附加到程序上对内存进行监测;AddressSanitizer则需要重新编译代码。所以,很多时候大家为了图方便,会优先使用Valgrind。

       但Valgrind会占用大量内存并明显拖慢程序运行的速度,这使得在部分场景下无法正常使用Valgrind。而AddressSanitizer在运行速度和效率上要比Valgrind好很多,所以在Valgrind无法完成检测时可以选择AddressSanitizer。

4.1、Valgrind介绍

       Valgrind是一套Linux下开放源代码(GPL V2)的仿真调试工具的集合,是运行在Linux 上的多用途代码分析和内存调试常用工具。Valgrind由内核(core)以及基于内核的其他调试工具组成。内核类似于一个框架(framework),它模拟了一个CPU环境,并提供服务给其他工具;而其他工具则类似于插件 (plug-in),利用内核提供的服务完成各种特定的内存调试任务。

       Valgrind是基于仿真的方式对程序进行调试,它先于应用程序获取实际处理器的控制权,并在实际处理器的基础上仿真一个虚拟处理器,并使应用程序运行于这个虚拟处理器之上,从而对应用程序的运行进行监视。

       应用程序并不知道该处理器是虚拟的还是实际的,已经编译成二进制代码的应用程序并不用重新进行编译,Valgrind 直接解释二进制代码使得应用程序基于它运行,从而能够检查内存操作时可能出现的错误。所以,在Valgrind下运行的程序运行速度要慢的多,而且使用的内存比目标程序要多的多,这也是Valgrind的一大劣势,这也导致部分场合下没法使用Valgrind去分析。

4.2、AddressSanitizer在速度和内存方面为什么明显优于Valgrind

       Valgrind采用的是二进制完全映射的影子内存技术,会占用更多内存才能去有效地监测内存变化。并且开启Valgrind监测之后,会严重降速,比如使用memcheck工具去监测内存,基本上是10到30倍的降速,明显的降速会导致我们的软件在业务上出现不可用的情况。关于降速,Valgrind官网上有着详细的说明:

The main one is that programs run significantly more slowly under Valgrind. Depending on which tool you use, the slowdown factor can range from 5-100. Memcheck runs programs about 10-30x slower than normal.

       而Google提供的内存检测工具AddressSanitizer在内存占用和运行速度方面有着卓越的表现,相比于Valgrind,AddressSanitizer的优势相当明显。AddressSanitizer采用了一种取巧的影子内存玩法,将虚拟地址空间的1/8分配给它的影子内存,并使用一个带有比例和偏移量的直接映射将一个应用程序地址转换为它相应的影子地址,确保了少量内存就能完成一个程序的监测。并且AddressSanitizer降速也比较少。AddressSanitizer在内存占用和降速方面,通过USENIX高等计算机系统协会某篇论文中的一段描述可以佐证:

We present AddressSanitizer, a new tool that combines performance and coverage. AddressSanitizer finds out-of-bounds accesses (for heap, stack, and global objects) and uses of freed heap memory at the relatively low cost of 73% slowdown,1.5x-4x memory overhead,making it a good choice for testing a wide range of C/C++ applications.

4.3、在很多实际项目中我们需要使用AddressSanitizer

       Valgrind采用的是二进制完全映射的影子内存技术,会占用更多内存才能去有效地监测内存变化,还会明显地拖慢程序的运行速度,可能会导致程序在收到请求后不能及时的响应,没法模拟出真实运行时的场景,可能就不一定能复现问题,甚至还会因为运行速度过慢导致程序根本无法正常的运转。所以我们有时需要使用占用内存少、运行速度更快的AddressSanitizer。

5、无法使用Valgrind的具体项目实例

​       在实际项目中我们遇到过不少无法使用Valgrind的场景。如果没有内存检测工具,排查起来效率非常低,仅仅通过打印日志和走读代码很难定位问题。如果有内存检测工具,可能很快就能定位出来。所以后来转向使用AddressSanitizer,很多Valgrind无法工作的场景,AddressSanitizer都可以胜任。与Valgrind相比,AddressSanitizer的运行速度是真的快,同时内存错误的检测能力也非常强。

5.1、使用Valgrind检测导致CPU占满,无法进行检测

       某客户现场我们的程序出现了内存异常问题,最先使用Valgrind进行检测,发现使用Valgrind检测时机器的CPU一直是100%,直接导致程序业务无法正常工作,由于业务无法运转,导致我们没有办法让程序跑到存在问题的流程,所以检测也就无法实施了。

5.2、使用Valgrind检测导致程序运行过慢,无法进行检测

       某客户现场出现了多线程死锁,使用gdb附加到目标程序上调试运行,发现某个公用模块每次都会检测到“它管理的堆的魔数被破坏”,于是强制退出了。由于该公用模块中内存管理器使用的地方比较多,包括上层业务代码和底层库,通过走读代码去分析哪些地方分配了堆内存很难实施。于是我们使用Valgrind分析,但因为速度过慢程序没法运转起来,内存检测任务无法实施。

6、AddressSanitizer与其他内存工具的比较

       AddressSanitizer与其他内存检测工具的比较如下所示:

Items \ Tools

AddressSanitizer

Valgrind/Memcheck

Dr. Memory

Mudflap

Guard Page

gperftools

technology

CTI

DBI

DBI

CTI

Library

Library

ARCH

x86,ARM,PPC,...

x86,ARM,PPC

x86

all(?)

all(?)

all(?)

OS

Linux, Mac, Windows, FreeBSD, Android

Linux, Mac

Windows, Linux

Linux, Mac(?)

All (1)

Linux, Windows

Slowdown

2x

20x

10x

2x-40x

?

?

Detects:

Heap OOB

yes

yes

yes

yes

some

some

Stack OOB

yes

no

no

some

no

no

Global OOB

yes

no

no

?

no

no

UAF

yes

yes

yes

yes

yes

yes

UAR

yes (see UseAfterReturn)

no

no

no

no

no

UMR

no (see MemorySanitizer)

yes

yes

?

no

no

Leaks

yes (see LeakSanitizer)

yes

yes

?

no

yes

上表中的相关名词说明如下:

DBI: dynamic binary instrumentation 
CTI: compile-time instrumentation 
UMR: uninitialized memory reads 
UAF: use-after-free (aka dangling pointer) 
UAR: use-after-return 
OOB: out-of-bounds 
x86: includes 32- and 64-bit. 
Guard Page: a family of memory error detectors (Electric fence or DUMA on Linux, Page Heap on Windows, Guard Malloc in Mac) gperftools: various performance tools/error detectors bundled with TCMalloc. Heap checker (leak detector) is only available on Linux. Debug allocator provides both guard pages and canary values for more precise detection of OOB writes, so it's better than guard page-only detectors.

7、如何使用AddressSanitizer?

​        从gcc 4.8开始,gcc才集成AddressSanitizer工具,所以要使用AddressSanitizer必须将gcc升级到4.8或以上版本。然后使用高版本gcc对代码进行重新编译,在编译时指定编译选项就可以了。

7.1、升级gcc版本

       可以到ftp://gcc.gnu.org/pub/gcc上下载高版本的gcc,然后到执行源码树中的contrib/download_prerequisites文件,它会下载和设置GCC编译依赖的组件。然后在GCC源码树同级的目录建立一个编译目录,比如叫build_dir,然后在该编译目录中执行如下命令进行编译和安装:

../src_dir/configure

make

make install

7.2、如何配置使用AddressSanitizer进行内存检测

        AddressSanitizer是内置在gcc中的,主要设置编译参数去设定是否启用AddressSanitizer的内存检测。

1)如果没使用makefile,直接gcc命令去编译,则在命令中添加-fsanitize=address选项,如下:

gcc  -fsanitize=address  -fno-omit-frame-pointer  -O1  -g  use-after-free.c  -o  use-after-free

其中:

1)用-fsanitize=address选项编译和链接你的程序。
2)用-fno-omit-frame-pointer编译,以得到更容易理解stack trace。
3)可选择-O1或者更高的优化级别编译

2)如果使用makefile,则在编译选项CFLAGS和链接选项LDFLAGS中都要添加-fsanitize=address选项,如下:

#都要追加-fsanitize=address开关
CFLAGS+=-fsanitize=address 
LDFLAGS+=-fsanitize=address

7.3、使用AddressSanitizer进行内存检测的实例

         比如下面的代码中,分配array数组并释放,然后返回它的一个元素,返回了一个已经释放了的内存地址:

int main (int argc, char** argv)
{int* array = new int[100];delete []array;return array[1];
}

上述代码放置在use-after-free.c中,直接使用gcc编译该文件即可,命令如下:

gcc  -fsanitize=address  -fno-omit-frame-pointer  -O1  -g  use-after-free.c  -o  use-after-free

然后,运行use-after-fee,AddressSanitizer检测了错误,就会打印出下面的信息:

==3189==ERROR: AddressSanitizer: heap-use-after-free on address 0x61400000fe44 
at pc 0x0000004008f1 bp 0x7ffc9b6e2630 sp 0x7ffc9b6e2620
READ of size 4 at 0x61400000fe44 thread T0#0 0x4008f0 in main /home/ron/dev/as/use_after_free.cpp:9#1 0x7f3763aa882f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)#2 0x4007b8 in _start (/home/ron/dev/as/build/use_after_free+0x4007b8)0x61400000fe44 is located 4 bytes inside of 400-byte region [0x61400000fe40,0x61400000ffd0)
freed by thread T0 here:#0 0x7f3763ef1caa in operator delete[](void*) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x99caa)#1 0x4008b5 in main /home/ron/dev/as/use_after_free.cpp:8#2 0x7f3763aa882f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)previously allocated by thread T0 here:#0 0x7f3763ef16b2 in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x996b2)#1 0x40089e in main /home/ron/dev/as/use_after_free.cpp:7#2 0x7f3763aa882f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)SUMMARY: AddressSanitizer: heap-use-after-free /home/ron/dev/as/use_after_free.cpp:9 main

如上图,打印出的信息主要分三部分:

1)ERROR部分:指出错误类型是heap-use-after-free;
2)READ部分:指出线程名thread T0,操作为READ,发生的位置是use-after-free.c:9(行号)。
该heapk块之前已经在use-after-free.c:8(行号)被释放了;
该heap块是在use-fater-free.c:7(行号)分配的。
3)SUMMARY部分:前面输出的概要说明。

7.4、使用AddressSanitizer的注意事项

       使用AddressSanitizer过程中可能会遇到一些问题,此处给大家讲几个注意事项。

1) 如果存在第三方内存管理器,可能需要取消对第三方管理器的依赖

       如果存在第三方内存管理器(比如tcmalloc),需要去掉第三方内存管理器的编译选项或连接选项,因为内存管理器分配的内存自身会预留一些管理空间,越界不多只写到这部分空间时,AddressSanitizer越界检测是不会认为它是异常的(因为它们仍然是用户分配的范围之内的,第三方内存管理器,与应用程序对于ASan没有差异的)。同时内存管理器通常会延迟释放内存,这也会影响检测的及时性。此外,如果链接时提示ASan中的符号找不到时给程序显示添加对libasan库的连接(默认在/usr/local/lib目录,找不时使用find命令找下)。

2)内存不足问题

       内存检测工具会增加程序的内存消耗,32位程序地址空间只有4G,用户态的通常只有3G,如果程序跑起来之后提示无法分配内存,可以通过设置如下两个选项缓解一下:

export ASAN_OPTIONS=quarantine_size_mb=256:start_deactivated=1。

其中:

quarantine_size_mb设置小点,牺牲使用已经释放了的内存问题的检测能力。
start_deactivated设置为1,启动时不会加载asan的全部功能,用于节省内存。

上面的选项只是缓解,根本的解决之道还是要开发64位版本的程序。

3)错误忽略

        有些错误我们改动不了或直接认为绝对安全,也可以在函数上面添加属性,进行错误忽略。比如:

#if defined(__clang__) || defined (__GNUC__)
# define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
#else
# define ATTRIBUTE_NO_SANITIZE_ADDRESS
#endif
...
ATTRIBUTE_NO_SANITIZE_ADDRESS
void ThisFunctionWillNotBeInstrumented() {...}

8、Windows平台高版本的Visual Studio也支持AddressSanitizer工具

       AddressSanitizer工具原先只支持Linux,现在也可以在Windows上使用了。微软在Visual Studio 2019的16.9版本们引入了AddressSanitizer,在安装Visual Studio 2019的16.9版本及以后的版本时,会默认安装AddressSanitizer工具:(默认勾选“C++ AddressSanitizer”)

       对于如何在VS中如何使用AddressSanitizer内存分析工具,可以看一下微软官方文章的详细说明:
在Visual Studio中使用AddressSanitizericon-default.png?t=N7T8https://docs.microsoft.com/zh-cn/cpp/sanitizers/asan?view=msvc-170此处我就不详细展开了,大家需要使用的话,可以去详细研究一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/134108.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

无需开通美团外卖会员一日三餐都可天天免费领取美团外卖红包优惠券?

美团外卖红包一天三餐都可用享优惠&#xff1f; 通过草柴公众号&#xff0c;回复美团外卖&#xff0c;天天都可以免费领取一次美团外卖节红包、天天神券1-3个。根据用餐标准早上吃少用3元天天神券、午餐吃饱用7元外卖节红包、晚餐吃好用6元外卖节红包。 *注&#xff1a;每天的…

stm32---定时器输入捕获

一、输入捕获介绍 在定时器中断实验章节中我们介绍了通用定时器具有多种功能&#xff0c;输入捕获就是其中一种。 STM32F1除了基本定时器TIM6和TIM7&#xff0c;其他定时器都具有输入捕获功能 。输入捕获可以对输入的信号的上升沿&#xff0c;下降沿或者双边沿进行捕获&#xf…

VR航天航空巡展VR科技馆航天主题科普设备沉浸遨游太空

每当飞机飞过头顶&#xff0c;我们总是忍不住抬头去仰望。从嫦娥奔月的神话传说&#xff0c;到莱特兄弟实现了上天翱翔的梦想&#xff0c;人类一直在不断探索更辽阔的天空和浩瀚的宇宙。 航空科普 寻梦而行 普乐蛙VR航天航空巡展&#xff0c;正在湖南郴州如火如荼的进行中&…

前端vue3分享——项目封装axios、vite使用env环境变量

文章目录 ⭐前言⭐vue3封装统一的axios请求&#x1f496; 请求拦截器 ⭐vue3使用env环境变量&#x1f496; vite env变量规则&#x1f496; vite.config获取env参数 ⭐总结&#x1f496; 编码sliod原则 ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于前端…

C. Manipulating History

Problem - 1688C - Codeforces 思路&#xff1a;因为它给定了最终的串&#xff0c;能够想到能够通过逆操作将整个序列变回去&#xff0c;那我们需要有一个形式str,a,b即在str中将a替换为b&#xff0c;很容易能够看出来&#xff0c;a中的字符串出现了两次&#xff0c;在str中一次…

关于老项目从JDK8升级到JDK17所需要注意的细节

文章目录 ☀️1.关于老项目从JDK8升级到JDK17所需要注意的细节&#x1f338;1.1.更新JDK&#x1f338;1.2.修改Idea中的JDK版本&#x1f338;1.3.关于修改过程中遇到的异常&#x1f338;1.4.IDEA工具栏操作Maven正常&#xff0c;但使用mvn命令运行就报错 ☀️1.关于老项目从JDK…

PCB layout在布线上的设计规范有哪些?

PCB Layout是一项技术活&#xff0c;也是经验活&#xff0c;良好的PCB Layout布线可帮助工程师确保最终的电路板性能、可靠性和制造质量&#xff0c;因此是很多电子工程师的学习重点&#xff0c;下面我们来盘点下PCB Layout关于布线的规范有哪些。 1、地管的引脚接地越短越好&a…

高阶数据结构(2)-----红黑树(未完成)

一)红黑树的基本概念和基本性质: 1)红黑树就是一种高度平衡的二叉搜索树&#xff0c;但是在每一个节点上面都增加了一个存储位来表示结点的颜色&#xff0c;可以是红色或者是黑色&#xff0c;通过对任何一条从根节点到叶子节点上面的路径各个节点着色方式的限制&#xff0c;红黑…

java:逆序排序的三种方法

// 逆序第一种方法 public static void main(String[] args) {int arr[] {11, 22, 33, 44, 55, 66};for (int i arr.length-1; i > 0; i--) {System.out.print("\t"arr[i]);}}缺点&#xff1a;这个是直接逆转&#xff0c;如果里面是随机数没办法比较 逆序第二种…

在ubuntu18.04上编译C++版本jsoncpp/opencv/onnxruntime且如何配置CMakelist把他们用起来~

这篇文章背景是笔者在ubuntu上编译C代码&#xff0c;依赖一些包&#xff0c;然后需要编译并配置到CMakelist做的笔记。主要也是一直不太懂CMakellist&#xff0c;做个笔记以防忘记&#xff0c;也给读者提供一站式的参考&#xff0c;可能您需要的不是这几个包&#xff0c;但大同…

【多区域电力系统模型】三区域电力系统的LQR和模糊逻辑控制(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【Python从入门到进阶】35、selenium基本语法学习

接上篇《34、selenium基本概念及安装流程》 上一篇我们介绍了selenium技术的基础概念以及安装和调用的流程&#xff0c;本篇我们来学习selenium的基本语法&#xff0c;包括元素定位以及访问元素信息的操作。 一、元素定位 Selenium元素定位是指通过特定的方法在网页中准确定位…

【教程】IDEA操作GIT

不小心推送代码之后 进行回退 1 找到需要回退的记录 比如要回退13分钟之前提交的代码 选中 右键还原提交 最后再重新推送被还原的提交 就可以了

ArcGIS10.1软件安装教程

ArcGIS10.1中英文&#xff08;32/64位)下载地址&#xff1a; 链接&#xff1a; https://pan.baidu.com/s/1Ksm112WaKMMk6La9ircCng 密码&#xff1a;t70f 安装步骤&#xff1a; 1、我们对安装包进行解压&#xff0c;直接鼠标右击解压即可。 2、 打开我们解压的文件夹&#…

【抖音小游戏】 Unity制作抖音小游戏方案 最新完整详细教程来袭【持续更新】

前言【抖音小游戏】 Unity制作抖音小游戏方案 最新完整详细教程来袭【持续更新】一、相关准备工作1.1 用到的相关网址1.2 注册字节开发者后台账号二、相关集成工作2.1 下载需要的集成资源2.2 安装StarkSDK和starksdk-unity-tools工具包2.3 搭建测试场景三、构建发布3.1 发布Nat…

01_网络编程_传统IO

网络编程 1.什么是网络编程 在网络通信协议下&#xff0c;不同计算机上运行的程序&#xff0c;进行的数据传输。 如果想把一个计算的结果&#xff0c;或者是电脑上的文件通过网络传递给你的朋友&#xff0c;就需要用到网络编程。 在实际生活中&#xff0c;网络通信无处不在…

linux相关知识以及有关指令3

在linux的世界中我们首先要有万物皆文件的概念&#xff0c;那么在系统中有那么多的文件&#xff0c;我们该怎么区分呢&#xff1f;文章目录 1. 文件分类2. 文件的权限1). 拥有者和所属组以及other2). 文件的权限3). 粘滞位4). 对于权限修改的拓展知识点a.修改权限b.修改拥有者所…

学校项目培训之Carla仿真平台之安装Carla

官网&#xff1a;http://carla.org/ 写在前面 由于安装都写了很多东西&#xff0c;所以我单独将安装弄出来记录一下。 如果你在安装9.12版本的时候遇到了很多问题&#xff0c;你可以考虑以下几点&#xff1a; - 楼梯可能不太行&#xff0c;需要更换&#xff0c;这是我实践得到的…

Jmeter 实现 mqtt 协议压力测试

1. 下载jmeter&#xff0c;解压 https://jmeter.apache.org/download_jmeter.cgi 以 5.4.3 为例&#xff0c;下载地址&#xff1a; https://dlcdn.apache.org//jmeter/binaries/apache-jmeter-5.4.3.zip linux下解压&#xff1a; unzip apache-jmeter-5.4.3.zip 2. 下载m…

Docker实战技巧(一):Kubernetes基础操作实战

Kubernetes定位在Saas层,重点解决了微服务大规模部署时的服务编排问题 1、关闭防火墙并设置开机禁用   systemctl stop firewalld   systemctl disable firewalld 2、配置repo   cd /etc/yum.repos.d/   下载Docker repo   wget https://mirrors.aliyun.com/docker-…