valgrind和Kcachegrind性能分析工具详解

2023-11-09

作者: zhuyong

原文地址

一、valgrind介绍

valgrind是运行在Linux上的一套基于仿真技术的程序调试和分析工具,用于构建动态分析工具的装备性框架。它包括一个工具集,每个工具执行某种类型的调试、分析或类似的任务,以帮助完善你的程序。Valgrind的架构是模块化的,所以可以容易的创建新的工具而又不会扰乱现有的结构。

valgrind主要包含以下工具:

1、memcheck:检查程序中的内存问题,如泄漏、越界、非法指针等。

2、callgrind:检测程序代码的运行时间和调用过程,以及分析程序性能。

3、cachegrind:分析CPU的cache命中率、丢失率,用于进行代码优化。

4、helgrind:用于检查多线程程序的竞态条件。

5、massif:堆栈分析器,指示程序中使用了多少堆内存等信息。

另外,也有一些大多数用户不会用到的小工具: Lackey是一个示例工具,用于演示一些装备的基础性内容;Nulgrind是一个最小化的Valgrind工具,不做分析或者操作,仅用于测试目的。

二、valgrind安装及使用
安装

建议从valgrind官网下载安装,目前官网的最新包是3.16.1

$ mkdir valgrind-inst
$ cd valgrind-inst/
$ wget https://sourceware.org/pub/valgrind/valgrind-3.16.1.tar.bz2

$ ls
valgrind-3.16.1.tar.bz2

解压后进行安装,可以指定安装目录,这样的话记得设置环境变量

$ tar -xvf valgrind-3.16.1.tar.bz2
$ cd valgrind-3.16.1
$ ./configure --prefix=/usr/local/valgrind
$ make
$ make install

查看是否安装成功

$ valgrind --version
valgrind-3.16.1
工具集的使用

基本使用格式如下:

usage: valgrind [options] prog-and-args

其支持众多选项,我们可以通过valgrind --help来进行查看。

这里我们只介绍几个较为常用的选项


--tool: 是最常用的选项,用于选择使用valgrind工具集中的哪一个工具。默认值为memcheck。

--version: 用于打印valgrind的版本号

-q/--quiet: 安静的运行,只打印错误消息;

-v/--verbose: 打印更详细的信息;

--trace-children: 是否跟踪子进程,默认值为no;

--track-fds: 是否追踪打开的文件描述符,默认为no

--time-stamp=no|yes: 是否在打印出的每条消息之前加上时间戳信息。默认值为no

--log-file=<file>: 指定将消息打印到某个文件

--default-suppressions: 加载默认的抑制参数。

--alignment: 指定malloc分配内存时的最小对齐字节数;

如下的一些选项用于Memcheck工具:

--leak-check=no|summary|full: 在退出时是否查找内存泄露。默认值为summary

--show-leak-kinds=kind1,kind2,..: 显示哪一种类型的内存泄露。默认显示definite和possible这两种;
三、 Valgrind 工具详解
1) memcheck

最常用的工具,用来检测程序中出现的内存问题,所有对内存的读写都会被检测到,一切对mallocfreenewdelete的调用都会被捕获。所以,它能检测以下问题:

1、使用未初始化的内存。如果在定义一个变量时没有赋初始值,后边即使赋值了,使用这个变量的时候Memcheck也会报"uninitialised value"错误。使用中会发现,valgrind提示很多这个错误,由于关注的是内存泄漏问题,所以可以用--undef-value-errors=选项把这个错误提示屏蔽掉,具体可以看后面的选项解释。

2、读/写释放后的内存块;

3、内存读写越界(数组访问越界/访问已经释放的内存),读/写超出malloc分配的内存块;

4、读/写不适当的栈中内存块;

5、内存泄漏,指向一块内存的指针永远丢失;

6、不正确的malloc/free或new/delete匹配(重复释放/使用不匹配的分配和释放函数);

7、内存覆盖,memcpy()相关函数中的dst和src指针重叠。
   

用法:

将程序编译生成可执行文件后执行:valgrind –leak-check=full ./程序名

注意:下面讨论的所有测试代码在编译时最好都加上-g选项(用来在memcheck的输出中生成行号)进行编译。

测试程序验证:

编写测试程序

#include <stdlib.h>

void func() {
    char *p = new char[10];
}

int main() {
    func();

    return 0;
}

编译后,用valgrind检测程序。
如果设置了--leak-check=fullMemcheck会给出详细的每个块是在哪里分配,并且给出分配时函数调用堆栈(编译的时候使用-g选项和去掉-o优化选项,就可以得到更详细的函数信息,可以精确到代码的某一行)。可以通过--show-leak-kinds选项来选择要详细报告哪几种类型的错误。Memcheck会把函数调用堆栈相同或相似的内存块信息,放到同一个条目来显示,可以通过--leak-resolution来控制这个"相似"判断的力度。

$ g++ -g -o test leak.cpp
$ valgrind --tool=memcheck --leak-check=full ./test

检测结果如下:

==6018== Memcheck, a memory error detector
==6018== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6018== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==6018== Command: ./test
==6018== 
==6018== 
==6018== HEAP SUMMARY:
==6018==     in use at exit: 10 bytes in 1 blocks
==6018==   total heap usage: 1 allocs, 0 frees, 10 bytes allocated
==6018== 
==6018== 10 bytes in 1 blocks are definitely lost in loss record 1 of 1
==6018==    at 0x4C2AC58: operator new[](unsigned long) (vg_replace_malloc.c:431)
==6018==    by 0x40062E: func() (leak.cpp:4)
==6018==    by 0x40063D: main (leak.cpp:8)
==6018== 
==6018== LEAK SUMMARY:
==6018==    definitely lost: 10 bytes in 1 blocks
==6018==    indirectly lost: 0 bytes in 0 blocks
==6018==      possibly lost: 0 bytes in 0 blocks
==6018==    still reachable: 0 bytes in 0 blocks
==6018==         suppressed: 0 bytes in 0 blocks
==6018== 
==6018== For lists of detected and suppressed errors, rerun with: -s
==6018== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

结果说明:

先看看输出信息中的HEAP SUMMARY,它表示程序在堆上分配内存的情况,其中的1 allocs
表示程序分配了 1 次内存,0 frees表示程序释放了 0 次内存,10 bytes allocated表示分配了 10 个字节的内存。
另外,Valgrind 也会报告程序是在哪个位置发生内存泄漏。

上面LEAK SUMMARY会打印5种不同的类型,这里我们简单介绍一下:

definitely lost: 明确丢失的内存。程序中存在内存泄露,应尽快修复。当程序结束时如果一块动态分配的内存没有被释放并且通过程序内的指针变量均无法访问这块内存则会报这个错误;

indirectly lost: 间接丢失。当使用了含有指针成员的类或结构体时可能会报这个错误。这类错误无需直接修复,它们总是与definitely lost一起出现,只要修复definitely lost即可。

possibly lost: 可能丢失。大多数情况下应视为与definitely lost一样需要尽快修复,除非你的程序让一个指针指向一块动态分配的内存(但不是这块内存的起始地址),然后通过运算得到这块内存的起始地址,再释放它。当程序结束时如果一块动态分配的内存没有被释放并且通过程序内的指针变量均无法访问这块内存的起始地址,但可以访问其中的某一部分数据,则会报这个错误。

stil reachable: 可以访问,未丢失但也未释放。如果程序是正常结束的,那么它可能不会造成程序崩溃,但长时间运行有可能耗尽系统资源。

其他几种情况,写一个综合的测试程序进行验证。

// mixed.cpp

void func() {
    char *ptr = new char[10];
    ptr[10] = 'a';   // 内存越界

    memcpy(ptr + 1, ptr, 5);   // 踩内存

    delete []ptr;
    delete []ptr; // 重复释放

    char *p;
    *p = 1;   // 非法指针
}

int main() {
    func();

    return 0;
}

编译后,用valgrind检测程序。

$ g++ -g -o test mixed.cpp
$ valgrind --tool=memcheck --leak-check=full ./test

检测结果

==22786== Memcheck, a memory error detector
==22786== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==22786== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==22786== Command: ./test
==22786== 
==22786== Invalid write of size 1      // 内存越界
==22786==    at 0x4007FB: func() (mixed.cpp:6)
==22786==    by 0x400851: main (mixed.cpp:18)
==22786==  Address 0x5a2404a is 0 bytes after a block of size 10 alloc'd
==22786==    at 0x4C2AC58: operator new[](unsigned long) (vg_replace_malloc.c:431)
==22786==    by 0x4007EE: func() (mixed.cpp:5)
==22786==    by 0x400851: main (mixed.cpp:18)
==22786== 
==22786== Source and destination overlap in memcpy(0x5a24041, 0x5a24040, 5)  // 踩内存
==22786==    at 0x4C2E83D: memcpy@@GLIBC_2.14 (vg_replace_strmem.c:1033)
==22786==    by 0x400819: func() (mixed.cpp:8)
==22786==    by 0x400851: main (mixed.cpp:18)
==22786== 
==22786== Invalid free() / delete / delete[] / realloc()    // 重复释放
==22786==    at 0x4C2BBAF: operator delete[](void*) (vg_replace_malloc.c:649)
==22786==    by 0x40083F: func() (mixed.cpp:11)
==22786==    by 0x400851: main (mixed.cpp:18)
==22786==  Address 0x5a24040 is 0 bytes inside a block of size 10 free'd
==22786==    at 0x4C2BBAF: operator delete[](void*) (vg_replace_malloc.c:649)
==22786==    by 0x40082C: func() (mixed.cpp:10)
==22786==    by 0x400851: main (mixed.cpp:18)
==22786==  Block was alloc'd at
==22786==    at 0x4C2AC58: operator new[](unsigned long) (vg_replace_malloc.c:431)
==22786==    by 0x4007EE: func() (mixed.cpp:5)
==22786==    by 0x400851: main (mixed.cpp:18)
==22786== 
==22786== Use of uninitialised value of size 8    // 非法指针
==22786==    at 0x400844: func() (mixed.cpp:14)
==22786==    by 0x400851: main (mixed.cpp:18)
==22786== 
==22786== 
==22786== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==22786==  Bad permissions for mapped region at address 0x4008B0
==22786==    at 0x400844: func() (mixed.cpp:14)
==22786==    by 0x400851: main (mixed.cpp:18)
==22786== 
==22786== HEAP SUMMARY:
==22786==     in use at exit: 0 bytes in 0 blocks
==22786==   total heap usage: 1 allocs, 2 frees, 10 bytes allocated
==22786== 
==22786== All heap blocks were freed -- no leaks are possible
==22786== 
==22786== Use --track-origins=yes to see where uninitialised values come from  
==22786== For lists of detected and suppressed errors, rerun with: -s
==22786== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

可见valgrind将上述几种情况都检测出来了。

2) Callgrind

gprof类似的分析工具,但它对程序的运行观察更为入微,能给我们提供更多的信息。和gprof不同的是,它不需要在编译源代码时附加特殊选项,但还是推荐加上调试选项。Callgrind收集程序运行时的一些数据,建立函数调用关系图,还可以有选择地进行cache模拟。在运行结束时,它会把分析数据写入一个文件。callgrind_annotate可以把这个文件的内容转化成可读的形式。

测试程序

#include <stdio.h>
#include <unistd.h>

void test() {
    sleep(1);
}
void func() {
    for(int i = 0; i < 10; i++) {
        test();
    }
}

int main() {
    func();
    printf("process is over!\n");

    return 0;
}

编译后,用valgrind检测程序。

$ g++ -g -o test callgrind.cpp
$ valgrind --tool=callgrind ./test
$ ls
callgrind.cpp  callgrind.out.3490  test

callgrind.out.3490就是callgrind生成的文件。

这里介绍一个图形化性能分析工具Kcachegrind

Kcachegrind官网地址

下载安装后可以用来分析callgrind生成的文件。

Kcachegrind打开callgrind.out.3490这个文件,如下图:

通过图形化,我们可以很直观的知道哪段程序执行慢,并且了解相关调用关系。

3) Cachegrind

Cache分析器,它模拟CPU中的一级缓存和二级缓存,能够精确地指出程序中cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。这对优化程序有很大的帮助。

它的使用方法也是:valgrind –tool=cachegrind ./程序名

4) Helgrind

它主要用来检查多线程程序中出现的竞争问题。Helgrind寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发觉的错误。Helgrind实现了名为Eraser的竞争检测算法,并做了进一步改进,减少了报告错误的次数。不过,Helgrind仍然处于实验状态。

测试代码:

#include <stdio.h>
#include <pthread.h>

#define NUM 10
int counter = 0;

void *threadfunc(void*) {
    for (int i = 0; i < NUM; i++) {
        counter += i;
    }
}

int main() {
    pthread_t tid1, tid2;

    pthread_create(&tid1, NULL, &threadfunc, NULL);
    pthread_create(&tid2, NULL, &threadfunc, NULL);

    // wait for thread to terminate
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    printf("counter = %d\n", counter);

    return 0;
}

编译后,用valgrind检测程序。

$ g++ -g -o test helgrind.cpp -lpthread
$ valgrind --tool=helgrind ./test

检测结果:

==27722== Helgrind, a thread error detector
==27722== Copyright (C) 2007-2017, and GNU GPL'd, by OpenWorks LLP et al.
==27722== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==27722== Command: ./test
==27722== 
==27722== ---Thread-Announcement------------------------------------------
==27722== 
==27722== Thread #3 was created
==27722==    at 0x597589E: clone (in /usr/lib64/libc-2.17.so)
==27722==    by 0x4E43059: do_clone.constprop.4 (in /usr/lib64/libpthread-2.17.so)
==27722==    by 0x4E44569: pthread_create@@GLIBC_2.2.5 (in /usr/lib64/libpthread-2.17.so)
==27722==    by 0x4C30CFA: pthread_create_WRK (hg_intercepts.c:425)
==27722==    by 0x4C31DD8: pthread_create@* (hg_intercepts.c:458)
==27722==    by 0x400728: main (helgrind.cpp:17)
==27722== 
==27722== ---Thread-Announcement------------------------------------------
==27722== 
==27722== Thread #2 was created
==27722==    at 0x597589E: clone (in /usr/lib64/libc-2.17.so)
==27722==    by 0x4E43059: do_clone.constprop.4 (in /usr/lib64/libpthread-2.17.so)
==27722==    by 0x4E44569: pthread_create@@GLIBC_2.2.5 (in /usr/lib64/libpthread-2.17.so)
==27722==    by 0x4C30CFA: pthread_create_WRK (hg_intercepts.c:425)
==27722==    by 0x4C31DD8: pthread_create@* (hg_intercepts.c:458)
==27722==    by 0x40070D: main (helgrind.cpp:16)
==27722== 
==27722== ----------------------------------------------------------------
==27722== 
==27722== Possible data race during read of size 4 at 0x601048 by thread #3
==27722== Locks held: none
==27722==    at 0x4006CE: threadfunc(void*) (helgrind.cpp:9)
==27722==    by 0x4C30EEE: mythread_wrapper (hg_intercepts.c:387)
==27722==    by 0x4E43EA4: start_thread (in /usr/lib64/libpthread-2.17.so)
==27722==    by 0x59758DC: clone (in /usr/lib64/libc-2.17.so)
==27722== 
==27722== This conflicts with a previous write of size 4 by thread #2
==27722== Locks held: none
==27722==    at 0x4006D9: threadfunc(void*) (helgrind.cpp:9)
==27722==    by 0x4C30EEE: mythread_wrapper (hg_intercepts.c:387)
==27722==    by 0x4E43EA4: start_thread (in /usr/lib64/libpthread-2.17.so)
==27722==    by 0x59758DC: clone (in /usr/lib64/libc-2.17.so)
==27722==  Address 0x601048 is 0 bytes inside data symbol "counter"
==27722== 
==27722== ----------------------------------------------------------------
==27722== 
==27722== Possible data race during write of size 4 at 0x601048 by thread #3
==27722== Locks held: none
==27722==    at 0x4006D9: threadfunc(void*) (helgrind.cpp:9)
==27722==    by 0x4C30EEE: mythread_wrapper (hg_intercepts.c:387)
==27722==    by 0x4E43EA4: start_thread (in /usr/lib64/libpthread-2.17.so)
==27722==    by 0x59758DC: clone (in /usr/lib64/libc-2.17.so)
==27722== 
==27722== This conflicts with a previous write of size 4 by thread #2
==27722== Locks held: none
==27722==    at 0x4006D9: threadfunc(void*) (helgrind.cpp:9)
==27722==    by 0x4C30EEE: mythread_wrapper (hg_intercepts.c:387)
==27722==    by 0x4E43EA4: start_thread (in /usr/lib64/libpthread-2.17.so)
==27722==    by 0x59758DC: clone (in /usr/lib64/libc-2.17.so)
==27722==  Address 0x601048 is 0 bytes inside data symbol "counter"
==27722== 
counter = 90
==27722== 
==27722== Use --history-level=approx or =none to gain increased speed, at
==27722== the cost of reduced accuracy of conflicting-access information
==27722== For lists of detected and suppressed errors, rerun with: -s
==27722== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

从上述结果知道,valgrind分析出了竞态的情况。

5) Massif

堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。Massif能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率。

Massif对内存的分配和释放做profile。程序开发者通过它可以深入了解程序的内存使用行为,从而对内存使用进行优化。这个功能对C++尤其有用,因为C++有很多隐藏的内存分配和释放。

此外,lackeynulgrind 也会提供。Lackey 是小型工具,很少用到;Nulgrind 只是为开发者展示如何创建一个工具。这里就不做介绍了。

参考列表

valgrind的使用

Linux 下利用 valgrind工具进行内存泄露检测和性能分析

valgrind详解与使用实例

使用 Valgrind 检测 C++内存泄漏

利用性能分析工具valgrind+KCachegrind分析

Linux性能分析工具与图形化方法

本文作者:zhuyong
原文链接:https://zhuyongchn.github.io
关于博主:欢迎关注左侧公众号,获取更多干货。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

valgrind和Kcachegrind性能分析工具详解 的相关文章

  • PyPI 上的轮子平台约束有什么限制吗?

    是否有任何地方 PEP 或其他地方 声明关于 Linux 轮子上传范围的限制 PyPI http pypi io 应该有 具体来说 上传是否被认为是可接受的做法linux x86 64轮子到 PyPI 而不是manylinux1 x86 6
  • pprof 和 ps 之间的内存使用差异

    我一直在尝试分析用 cobra 构建的 cli 工具的堆使用情况 这pprof工具显示如下 Flat Flat Sum Cum Cum Name Inlined 1 58GB 49 98 49 98 1 58GB 49 98 os Read
  • 从c调用汇编函数

    我试图从 c 调用汇编函数 但我不断收到错误 text globl integrate type integrate function integrate push ebp mov esp ebp mov 0 edi start loop
  • 推荐用于小型站点的 IRC 服务器 (ircd)? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 情况 我想使用 IRC 机器人作为我正在研究的其他代码的通用通信接口 服务器硬件陈旧且内存不足 但运行在相对最新的 Debian GNU
  • Linux“屏幕”的 Windows 等效项还是其他替代方案?

    我正在寻找一种在 Windows 环境中控制程序的方法 我希望它与 Linux 软件有点相似 screen 我搜索的原因是我需要使用标识符启动一个程序 在 Windows 上 这样我以后就能够关闭该特定程序 而无需关闭其他任何程序 即使实际
  • 从 php/linux 获取 pdf 的布局模式(横向或纵向)

    给定一个 PDF 如何使用 PHP lib 或 Linux 命令行工具获取 PDF 的布局模式 或相对宽度 高度 Using http www tecnick com public code cp dpage php aiocp dp tc
  • 如何从 Linux 内核模块获取使用计数?

    我对正在开发的内核模块的使用计数有疑问 我想打印它以进行调试 如何从模块代码中获取它 有问题的内核版本 Linux 2 6 32 module refcount http lxr linux no linux v2 6 34 1 inclu
  • 在 Linux 上创建线程与进程的开销

    我试图回答在 python 中创建线程与进程有多少开销的问题 我修改了类似问题的代码 该问题基本上运行一个带有两个线程的函数 然后运行带有两个进程的相同函数并报告时间 import time sys NUM RANGE 100000000
  • 无需 root 访问权限即可安装 zsh? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 有可能 以及如何 我确实需要在几台具有 ssh 访问权限 但没有 root 访问权限 的远程计算机上使用此功能 下载 zsh wget O zsh t
  • 如何重命名 .tar.gz 文件而不提取内容并在 UBUNTU 中创建新的 .tar.gz 文件?

    我有一个命令将创建一个新的 tar gz现有文件中的文件 sudo tar zcvf Existing tar gz New tar gz 该命令将创建一个新的New tar gz从现有的文件Existing tar gz file 谁能告
  • 计算 TCP 重传次数

    我想知道在LINUX中是否有一种方法可以计算一个流中发生的TCP重传的次数 无论是在客户端还是服务器端 好像netstat s解决了我的目的
  • 如何反汇编、修改然后重新组装 Linux 可执行文件?

    无论如何 这可以做到吗 我使用过 objdump 但它不会产生我所知道的任何汇编器都可以接受的汇编输出 我希望能够更改可执行文件中的指令 然后对其进行测试 我认为没有任何可靠的方法可以做到这一点 机器代码格式非常复杂 比汇编文件还要复杂 实
  • 如何在perl中使用O_ASYNC和fcntl?

    我想使用 O ASYNC 选项 当管道可以读取时 SIGIO 的处理程序将运行 但以下代码不起作用 任何人都可以帮助我吗 bin env perl use Fcntl SIG IO sub print catch SIGIO n my fl
  • 在非实时操作系统/内核上执行接近实时任务的最佳方法是什么?

    在一台 GNU Linux 机器上 如果想要执行 实时 亚毫秒级时间关键 任务 您几乎总是必须经历漫长 复杂且容易出现问题的内核补丁过程 以提供足够的支持 1 http en wikipedia org wiki RTLinux Backg
  • Bash - 比较 2 个文件列表及其 md5 校验和

    我有 2 个列表 其中包含带有 md5sum 检查的文件 即使文件相同 列表也具有不同的路径 我想检查每个文件的 md5 和 我们正在讨论数千个文件 这就是为什么我需要脚本来仅显示差异 第一个列表是普通列表 第二个列表是文件的当前状态 我想
  • Visual Studio - X11:缺少 DISPLAY 环境变量

    我正在使用 Visual Studio 2019 Enterprise 开发跨平台 Windows Linux x64 GUI 应用程序 在这个 2019 版本中 我们可以使用 Visual Studio调试平台 Windows 本机 和
  • 如何使用 go1.6.2 构建 linux 32 位

    有没有任何组合GOARCH and GOOS我可以设置哪些值来构建 ELF 32 位二进制文 件 GOOS linux and GOARCH 386 更多示例 架构 32 bit gt GOARCH 386 64 bit gt GOARCH
  • php_network_getaddresses: getaddrinfo 失败: 名称或服务未知 (0) 连接失败..!

    我正在使用 php 邮件程序功能 但出现以下错误 如何修复它 2016 01 22 06 15 48 SMTP 错误 无法连接到服务器 php network getaddresses getaddrinfo失败 名称或服务未知 0 连接失
  • 从哪里获取 iostream.h

    我正在尝试在 Linux 中做一些事情 但它抱怨找不到 iostream h 我需要安装什么才能获取此文件 这个标准头的正确名称是iostream没有扩展名 如果您的编译器仍然找不到它 请尝试以下操作 find usr include na
  • 如何使用 VSCode 调试 Linux 核心转储?

    我故意从我使用 VSCode 编写的 C 应用程序生成核心转储 我不知道如何调试核心转储 有没有人愿意分享这方面的经验 更新 我相信我现在已经可以使用了 我为核心文件创建了第二个调试配置 我需要添加指向生成的转储文件的 coreDumpPa

随机推荐

  • nft术语解释

    NFT 爱好者 原文用的是nerds 翻译作书呆子 我感觉不太合理 我写成爱好者 在谈论这个东西时候总是会有一堆让人眼花缭乱的术语 对非圈内人来说会感觉难以理解 这里整理了23个术语解释来帮助你理解 作为nerds的其中之一 我过滤掉了一些
  • Mysql中的日期与时间类型

    MySQL有多种表示日期和时间的数据类型 不同的版本可能有所差异 MySQL8 0版本支持的日期和时间类型主要有 YEAR类型 TIME类型 DATE类型 DATETIME类型和TIMESTAMP类型 YEAR类型通常用来表示年 DATE类
  • Vue Cli3.x-4.x 实现rem适配

    Vue移动端rem适配 1 安装lib flexible和postcss px2rem npm install lib flexible save npm install postcss px2rem save 2 在main js中引入l
  • JavaScript 数组塌陷

    概念 数组塌陷 在对数组进行操作的时候 会使数组的长度产生变化 同时 操作的数组那个项的下一个索引会被跳过 从而造成数组的某项会被跳过 这种叫做数组塌陷现象 例子 let arr 1 2 3 3 3 3 3 3 3 4 5 6 7 8 9
  • Nodejs 快速学习

    1 Nodejs快速入门 1 1 安装 官网 https nodejs org zh cn download 一路next安装即可 cmd查看 是否 安装成功 1 2 什么是Nodejs 注意 ES6语法完全兼容 1 3 第一个Nodejs
  • [python+nltk] 自然语言处理简单介绍和NLTK坏境配置及入门知识(一)

    本文主要是总结最近学习的论文 书籍相关知识 主要是Natural Language Pracessing 自然语言处理 简称NLP 和Python挖掘维基百科Infobox等内容的知识 此篇文章主要参考书籍 Natural Language
  • 恶意URL数据集

    一些URL数据集的收集来源 1 https openphish com feed txt 2 https ransomwaretracker abuse ch blocklist 3 https www phishtank com 4 ht
  • SnackBar 简单使用

    1 简介 Snackbar是Android Support Design Library库中的一个控件 可以在屏幕底部快速弹出消息 比Toast更加好用 可以添加点击行为 多用于结合协调布局使用 CoordinatorLayout impl
  • 全国身份证身份数据库sql(2021最新)

    为方便下载 已经将 sql 文件上传CSDN 链接 http download csdn net download leiflyy 10143794 insert into areazone areazone province city z
  • linux的dirty page回写磁盘过程中是否允许并发写入更新page?

    概述 众所周知Linux内核write系统调用采用pagecache机制加速写入过程 避免write系统调用长时间block应用进程 用户态进程执行write调用的时候 内核只是将用户态buffer copy到内核的pagecache当中
  • Golang Gorm 创建HOOK

    创建的时候 在插入数据之前 想要做一些事情 钩子函数比较简单 就是实现before create的一个方法 package main import gorm io driver mysql gorm io gorm type Student
  • maven安装

    1 maven 安装 需要使用maven命令 在需要的的操作系统中 安装maven插件 这里我用是Windows操作系统 2 在Windows安装maven 1 安装jdk 2 下载地址http maven apache org 3 解压后
  • Streamlit 讲解专栏(九):深入探索布局和容器

    文章目录 1 前言 2 st sidebar 在侧边栏增添交互元素 2 1 将交互元素添加至侧边栏 2 2 示例 在侧边栏添加选择框和单选按钮 2 3 特殊元素的注意事项 3 st columns 并排布局多元素容器 3 1 插入并排布局的
  • 揭秘最领先的Llama2中文大模型!

    导语 国内最大的开源社区 Llama中文社区率先完成了国内首个真正意义上的中文版Llama2 13B大模型 从模型底层实现了Llama2中文能力的大幅优化和提升 毋庸置疑 中文版Llama2一经发布开启了国内大模型新时代 全球最强 但中文短
  • Mybatis-动态sql和分页

    目录 一 什么是Mybatis动态分页 二 mybatis中的动态SQL 在BookMaaper xml中写sql BookMapper BookBiz接口类 BookBizImpl实现接口类 demo测试类 编辑 测试结果 三 mybat
  • C语言创建一个二叉树

    如何创建一个二叉树 先序遍历 中序遍历 include
  • 应用程序图标丢失问题的解决办法?

    如果是某一特定文件类型的 根据扩展名 的问题 是文件关联的问题 去注册表里寻找答案吧 用setup factory制作的安装包 之前一直都挺正常的 今天怎么试了一下 有时有图标有时没有 奇怪的很 于是追查了一下 原来我是因为我是在32位系统
  • 在cmd中,如何使用cd进入指定文件目录

    1 要进入的磁盘与当前磁盘一致 例如 cd C Program Files x86 Google Chrome Application 2 进入到其他磁盘 例如 cd d D JAVA codes 01 1 4 或者下面的方式 直接输入磁盘
  • Unity中Cg的基本语法和使用

    Cg是类似于C语言的发展起来的图形编程语言 Cgraphics 它的很多表达式if else 和C语言非常相像 也和C 非常相像 由于Shader是写给显卡执行的 所以没有输出语句来调试 很多地方调试不了 只能靠Unity编辑器来帮我们报错
  • valgrind和Kcachegrind性能分析工具详解

    作者 zhuyong 原文地址 一 valgrind介绍 valgrind是运行在Linux上的一套基于仿真技术的程序调试和分析工具 用于构建动态分析工具的装备性框架 它包括一个工具集 每个工具执行某种类型的调试 分析或类似的任务 以帮助完