为什么选择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++常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/125529931C++软件分析工具从入门到精通案例集锦(专栏文章正在更新中...)https://blog.csdn.net/chenlycly/article/details/131405795C/C++基础与进阶(专栏文章,持续更新中...)https://blog.csdn.net/chenlycly/category_11931267.html C++程序中大部分问题都是内存问题,有些可以快速定位,有些则很难排查,通过日志打印及代码走读很难定位,并且有些难缠的问题只在客户的环境中才会出现(在公司内部测试环境中无法复现),处理起来非常头疼,把人搞的精疲力竭后可能还查不出来。今天给大家介绍来自Google的强大C/C++内存检测工具AddressSanitizer,它可以很好地解决实际应用环境中很多无法快速定位的内存问题。
1、C++程序中的内存问题
在C++程序中,大部分程序运行异常都是内存问题引起的,内存问题也是最让C++程序员头疼的事情。常见的内存异常有空指针、野指针、线程栈溢出、内存越界(栈内存越界、堆内存越界和全局内存越界)、堆内存被破坏、内存泄漏、虚拟内存不足等,如下所示:
其中某些场景下的内存越界问题以及堆内存被破坏问题最为难查,特别是堆内存被破坏问题。一般堆内存被破坏会表现为,程序到处胡乱崩溃,一会崩在这里,一会崩在那里!因为堆内存被破坏,一会崩溃在new的地方,一会崩溃在delete的地方!
关于C++软件异常及内存错误的详细说明,我就不在此赘述了,感兴趣的,可以去看看我之前写的文章:
C++软件异常分析概述https://blog.csdn.net/chenlycly/article/details/123991269引发C++程序内存错误的常见原因分析与总结https://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中使用AddressSanitizerhttps://docs.microsoft.com/zh-cn/cpp/sanitizers/asan?view=msvc-170此处我就不详细展开了,大家需要使用的话,可以去详细研究一下。
相关文章:
为什么选择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…...
获取vue当前页面url问号后面的参数
除了使用 window.location.search 或 Vue Router 的 $route.query 来获取 URL 问号后面的参数之外,您还可以使用 JavaScript 中的正则表达式来解析 URL 中的参数部分。以下是一个示例: // 获取当前页面的完整 URL const currentURL window.location.hre…...
Linux编程之线程池的设计与实现
Linux编程之线程池的设计与实现(C98) 代码 假设服务器的硬件资源“充裕”,那么提高服务器性能的一个很直接的方法就是空间换时间, 即“浪费”服务器的硬件资源,以换取其运行效率。 提升服务器性能的一个重要方法就是…...
stm32---定时器输入捕获
一、输入捕获介绍 在定时器中断实验章节中我们介绍了通用定时器具有多种功能,输入捕获就是其中一种。 STM32F1除了基本定时器TIM6和TIM7,其他定时器都具有输入捕获功能 。输入捕获可以对输入的信号的上升沿,下降沿或者双边沿进行捕获…...
打造生产级Llama大模型服务
对于任何想要尝试人工智能或本地LLM,又不想因为意外的云账单或 API 费用而感到震惊的人,我可以告诉你我自己的旅程是如何的,以及如何开始使用廉价的消费级硬件执行Llama2 推理 。 这个项目一直在以非常活跃的速度发展,这使得它非…...
Acwing 828. 模拟栈
Acwing 828. 模拟栈 题目要求思路讲解代码展示 题目要求 思路讲解 栈:先进后出 队列:先进先出 代码展示 #include <iostream>using namespace std;const int N 100010;int m; int stk[N], tt;int main() {cin >> m;while (m -- ){string o…...
初识Docker
文章目录 Docker安装Docker简介1.什么是虚拟化、容器化?2. 为什么需要虚拟化、容器化?3. 虚拟化的实现方式主机虚拟化的实现方式容器虚拟化实现 4. 虚拟机和Docker的区别 Docker安装 基于Centos7进行安装 1.确认系统版本和CPU架构,Centos7的x86_64架构…...
HTTPS Tomcat Servlet 博客系统 软件测试的概念 Linux
第 1 题(多选题) 题目名称: 以下关于http和https说法正确的是 题目内容: A .http是超文本传输协议 B .https是超文本传输安全协议 C .http是明文传输 D .https是加密传输 第 2 题(单选题) 题目名称…...
云南财经大学《乡村振兴战略下传统村落文化旅游设计》许少辉八一著作
云南财经大学《乡村振兴战略下传统村落文化旅游设计》许少辉八一著作...
shopee——排序模型AUC还能涨吗?
文章目录 CBMRMultiCBMRSample Weight Assignment多任务推荐模型 CBMR MultiCBMR Sample Weight Assignment Click-aware Structure Transfer with Sample Weight Assignment for Post-Click Conversion Rate Estimation 每个用户的top-k 邻居每个商品的top-k 邻居平滑处理并构…...
长城网络靶场第三题
关卡描述:1.oa服务器的内网ip是多少? 先进行ip统计,开始逐渐查看前面几个ip 基本上都是b/s,所以大概率是http,过滤一下ip 第一个ip好像和oa没啥关系 第二个ip一点开就是 oa,应该就是他了。 关卡描述&a…...
Java“牵手”虾皮商品列表页数据采集+虾皮商品价格数据排序,虾皮API接口申请指南
虾皮商城是一个在线电子商务平台,总部设在新加坡,隶属于Sea Limited(冬海集团,简称为Sea)。虾皮商城于2015年在新加坡成立以来,业务范围辐射新加坡、马来西亚、菲律宾、泰国、越南、巴西等10余个市场1。拥有…...
Pyspark综合案例(pyspark安装和java运行环境配置)
一、RDD对象 PySpark支持多种数据的输入,在输入完成后,都会得到一个:RDD类的对象 RDD全称为:弹性分布式数据集(Resilient Distributed Datasets) PySpark针对数据的处理,都是以RDD对象作为载…...
虚拟机突然无法访问外部网络的现象集合
现场还原 虚拟机突然无法访问外部网络 ping 8.8.8.8的时候显示网络不可达 ping 8.8.8.8ping www.baidu.com(报:未知的名称或服务或请求超时) ping www.baidu.comyum操作 也提示错误:为仓库 ‘appstream’ 下载元数据失败 : C…...
国庆中秋特辑(一)浪漫祝福方式 用循环神经网络(RNN)或长短时记忆网络(LSTM)生成祝福诗词
目录 一、使用深度学习中的循环神经网络(RNN)或长短时记忆网络(LSTM)生成诗词二、优化:使用双向 LSTM 或 GRU 单元来更好地捕捉上下文信息三、优化:使用生成对抗网络(GAN)或其他技术…...
【入门篇】ClickHouse 的安装与配置
文章目录 0. 前言ClickHouse的安装1. 添加 ClickHouse 的仓库2. 安装 ClickHouse3. 启动 ClickHouse 服务器4. 使用 ClickHouse 客户端 ClickHouse的配置 1. 详细安装教程1.1. 系统要求1.1. 可用安装包 {#install-from-deb-packages}1.1.1. DEB安装包1.1.1. RPM安装包 {#from-r…...
为了工作刷题
1.同步通信和异步通信有什么区别?UART、SPI和I2C分别属于什么类型的通信方式? 同步通信:在同步通信中,发送方和接收方之间使用共享的时钟信号来同步数据传输。发送方按照时钟信号的边沿(上升沿或下降沿)将数…...
linux jenkins2.414.1-1.1版本安装
文章目录 前言一、rpm文件下载二、安装jenkins2.1.升级jdk1.82.2安装jenkins2.3 启动服务2.4 使用密码登录2.5 修改插件源2.6 汉化插件安装演示 总结 前言 之前也安装过jenkins,但是那个版本是2.1的,太老了很多插件都不支持,现在安装目前为止…...
嵌入式学习笔记(33)S5PV210的第二阶段处理过程
(1)第一个过程,怎么找到具体是哪个中断:S5PV210中因为支持的中断源很多,所以直接设计了4个中断寄存器,每个32位,每位对应一个中断源。(理论上210最多可以支持128个中断源,…...
学校项目培训之Carla仿真平台之安装Carla
官网:http://carla.org/ 写在前面 由于安装都写了很多东西,所以我单独将安装弄出来记录一下。 如果你在安装9.12版本的时候遇到了很多问题,你可以考虑以下几点: - 楼梯可能不太行,需要更换,这是我实践得到的…...
什么是MQ消息队列及四大主流MQ的优缺点(个人网站复习搬运)
什么是MQ消息队列及四大主流MQ的优缺点 小程序要上一个限时活动模块,需要有延时队列,从网上了解到用RabbitMQ可以解决,就了解了下 MQ 并以此做记录。 一、为什么要用 MQ 核心就是解耦、异步和…...
Learn Prompt-什么是ChatGPT?
ChatGPT(生成式预训练变换器)是由 OpenAI 在2022年11月推出的聊天机器人。它建立在 OpenAI 的 GPT-3.5 大型语言模型之上,并采用了监督学习和强化学习技术进行了微调。 ChatGPT 是一种聊天机器人,允许用户与基于计算机的代理进行对…...
高德地图实现-微信小程序地图导航
效果图: 一、准备阶段 1、在高德开放平台注册成为开发者2、申请开发者密钥(key)。3、下载并解压高德地图微信小程序SDK 高德开放平台: 注册账号(https://lbs.amap.com/)) 申请小程序应用的 key 应用管理(https://console.ama…...
你已经应用了哪种服务注册和发现的模式呢?
前面历史文章中我们有说过关于微服务的注册和发现,并以 etcd 作为简单例子简单阐述了关于服务注册和发现的应用 那么日常工作中,你已经使用了服务注册和发现的哪些模式呢? 服务注册和发现的作用 首先,简单说明一下服务注册和发…...
Python爬虫技术在SEO优化中的关键应用和最佳实践
大家好!今天我要和大家分享一个关于SEO优化的秘密武器:Python爬虫技术。在这篇文章中,我们将探讨Python爬虫在SEO优化中的关键应用和最佳实践。无论您是一名SEO专家、网站管理员,还是对优化网站曝光度感兴趣的初学者,都…...
基于支持向量机的试剂条图像识别,基于SVM的图像识别,SVM的详细原理,Libsvm工具箱使用注意事项
目录 支持向量机SVM的详细原理 SVM的定义 SVM理论 Libsvm工具箱详解 简介 参数说明 易错及常见问题 代码下载链接: 基于支持向量机SVM的试剂条图像自动识别,基于SVM的试剂条图像自动读取资源-CSDN文库 https://download.csdn.net/download/abc991835105/88215944 SVM应用实例…...
PbootCMS在搭建网站
1、打开网站 https://www.pbootcms.com/ 2、点击 “本站” 下载最新的网站代码 3、在本地laragon/www下创建目录(hejuwuye),并将代码放进去 4、创建本地数据库,数据库名称为: hejuwuye,然后将static/bac…...
C语言经典100例题(56-60)--画圆;画方;画线
目录 【程序56】题目:画图,学用circle画圆形 【程序57】题目:画图,学用line画直线。 【程序58】题目:画图,学用rectangle画方形。 【程序59】题目:画图,综合例子。 【程序60】题…...
linux相关知识以及有关指令3
在linux的世界中我们首先要有万物皆文件的概念,那么在系统中有那么多的文件,我们该怎么区分呢?文章目录 1. 文件分类2. 文件的权限1). 拥有者和所属组以及other2). 文件的权限3). 粘滞位4). 对于权限修改的拓展知识点a.修改权限b.修改拥有者所…...
关于Synchronized
Synchronized用于实现线程间的同步。它可以被用于方法或代码块上,确保同一时间只有一个线程可以访问被 synchronized 修饰的代码,也就是常说的锁,synchronized有三点作用 1)实现线程安全:通过使用 synchronized&#x…...
网站发帖做业务/比较好的搜索引擎
为什么80%的码农都做不了架构师?>>> /*** Created by liuhu on 2017/6/23.* 微信获取签名* 对于签名需要对token ticket做服务端缓存以防api调用次数超过上限*/ const request require("request"); const sha1 require("sha1"); …...
旅游网站开发毕业论文前言/搜索引擎收录提交入口
用户在使用经典虚拟机时,经常会有如下疑问:门户主板页面中的 SSH/RDP 证书指纹这项信息是怎么来的?用途是什么?为什么有的时候为空?有没有对虚拟机使用有什么影响?以下我们进行一些基本的介绍: …...
Wordpress 页面拼接/电脑系统优化工具
问题描述 我的DB2多分区数据库(DPF)环境,操作系统时间被意外/人工修改了,现在我修改回来之后,发现所有的更新操作都会失败(insert/delete/update/import/create/load&…...
网站企业建站/seo1域名查询
还是畅通project Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 26860 Accepted Submission(s): 11985Problem Description某省调查乡村交通状况,得到的统计表中列出了随意两村庄间的距离。省政府“…...
软件下载网站怎么做/搜索引擎优化网页
本博客采用 CC BY-NC-SA 4.0 进行许可 转载于:https://www.cnblogs.com/GavinZheng/p/10799212.html...
新疆生产建设兵团人社厅网站/衡水seo营销
一、题目[LeetCode-38] 给定一个正整数 n ,输出外观数列的第 n 项。 「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。 你可以将其视作是由递归公式定义的数字字符串序列: countAndSay(1) &quo…...