精华内容
下载资源
问答
  • linux段错误核心已转储
    万次阅读
    2019-02-23 10:19:03

    在终端输入:ulimit -a

    会发现提示很多

    重点关注两个,一个是core file size,还有一个是stack size


    vi .bashrc

    在bashrc文件最后加

    ulimit -c unlimited

    ulimit -s 819200

    保存后关闭终端

     

    更多相关内容
  • C/C++开发者经常会遇到段错误(segfault),定位很困难。在开发环节可以用单元测试等手段,但是在线上环境可能没有基本的...本文介绍在linux下如何调试 段错误(核心已转储) Segmentation fault (core dumped) 问题。

    linux下调试段错误(核心已转储) Segmentation fault (core dumped)


    如需转载请标明出处:http://blog.csdn.net/itas109
    QQ技术交流群:129518033

    前言

    C/C++开发者经常会遇到段错误(segfault),定位很困难。在开发环节可以用单元测试等手段,但是在线上环境可能没有基本的开发调试工具,这种情况下就需要一些调试方法。本文介绍在linux下如何调试段错误(核心已转储) Segmentation fault (core dumped) 问题。

    1. 基础知识

    1.1 段错误简介

    段错误就是指应用程序访问的内存超出了系统所给的内存空间 。

    可能导致段错误的原因有:

    • 访问系统数据区,最常见就是操作0x00地址的指针
    • 内存越界(数组越界,变量类型不一致等): 访问到不属于你的内存区域
    • 栈溢出(Linux一般默认栈空间大小为8192kb,ulimit -s命令查看)

    1.2 段错误典型错误代码

    1.2.1 访问系统数据区

    #include <stdio.h>
    int main(void)
    {
    	int*ptr = NULL;
    	*ptr = 1;// 给0地址写值
    	return 0;
    }
    

    对于指针的使用,以下是指针的典型正确使用

    // main.cpp
    // gcc -g main.cpp -o main -lstdc++
    // g++ -g main.cpp -o main
    
    #include <stdio.h>
    int main(void)
    {
    	int* ptr = NULL; // 1. 指针初始化为NULL(C++11建议使用nullptr)
    	ptr = new int(); // 2. 为指针申请内存
    	if(ptr == NULL) // 3. 判断是否申请内存成功
    	{
    		printf("memory new error");
    		return 0;
    	}
    
        // 4. 使用指针(使用前判空)
    	if(ptr != NULL)
    	{
    		*ptr = 1; 
    		printf("ptr: %d", *ptr);
    	}
    	
    	// 5. 释放指针并置空
    	if(ptr != NULL)
    	{
    		delete ptr; // 防止内存泄漏(new与delete成对存在)
    		ptr = NULL; // 释放后置空,防止野指针
    	}
    	
    	return 0;
    }
    

    1.2.2 内存越界

    #include <stdio.h>
    int main(void)
    {
        char*s ="test";
        *s ='a';// 写入只读内存
        return 0;
    }
    
    #include <stdio.h>
    int main(void)
    {
        char s[1];
        printf("%c", s[99999]); // 数组越界访问
        return 0;
    }
    

    1.2.3 栈溢出

    #include <stdio.h>
    
    int main(void)
    {
    	char temp[1024*1024*8] = {0}; // 栈溢出(ulimit -s 默认为8192kb)
        
        return 0;
    }
    

    2. 段错误信息获取

    #include <stdio.h>
    int main(void)
    {
    	int*ptr = NULL;
    	*ptr = 1;// 给0地址写值
    	return 0;
    }
    

    编译命令

    gcc -g main.cpp -o main
    

    2.1 dmesg

    dmesg是(显示或驱动程序)消息。它用于检查或控制内核环形缓冲区。

    $ dmesg 
    ...
    [131196.647617] main[60331]: segfault at 0 ip 00000000004004fd sp 00007ffe3dd49f10 error 6 in main[400000+1000]
    

    字段说明:

    segfault at 引起故障的地址
    ip 指令的内存地址
    sp 堆栈指针地址, 及栈顶指针

    error number是由三个字位组成的,从高到底分别为bit2 bit1和bit0,所以它的取值范围是0~7.

    bit 2 ==	 0: kernel-mode access	1: user-mode access
    bit 1 ==	 0: read access		1: write access
    bit 0 ==	 0: no page found	1: protection fault
    

    因此,以上的段错误定位为user-mode access和write access,也就是用户态内存写入访问越界

    2.2 系统日志/var/log/messages

    系统日志/var/log/messages 包含全局系统消息,包括系统启动期间记录的消息,如mail,cron,daemon,kern,auth等

    $ sudo cat /var/log/messages
    ...
    Mar 30 10:49:52 localhost kernel: main[60331]: segfault at 0 ip 00000000004004fd sp 00007ffe3dd49f10 error 6 in main[400000+1000]
    

    3. 段错误的调试

    3.1 gdb调试

    适用场景:

    • 适合于在生产环境下调试程序的段错误

    • 当程序很复杂,core文件相当大时,该方法不可用

    3.1.1 开启生成core文件

    查看生成core文件是否开启(0表示未开启)

    $ ulimit -c 
    0
    

    设置生成core文件

    $ ulimit -c unlimited
    

    3.1.2 gdb调试core文件

    $ gdb main core.83505
    
    ...
    Core was generated by `./main'.
    Program terminated with signal 11, Segmentation fault.
    #0  0x00000000004004fd in main () at main.cpp:5
    5               *ptr = 1;// 给0地址写值
    Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7.ns7.01.x86_64
    (gdb) bt
    #0  0x00000000004004fd in main () at main.cpp:5
    ...
    

    3.2 objdump反汇编调试

    适用场景

    • 不需要-g参数编译,不需要借助于core文件,但需要有汇编基础

    • 使用了gcc编译优化参数(-O1,-O2,-O3)时,生成的汇编指令将会被优化,使得调试过程更加复杂

    指令地址00000000004004fd,main起始映射地址400000,计算指令的偏移地址:4004fd- 400000= 004fd

    objdump -ld main > dumpcode 
    

    其中,-l 表示在输出中包含行号和文件名(编译时使用-g生成)

    00000000004004ed <main>:
    main():
    /mnt/hgfs/vm_share/cpp/main.cpp:3
      4004ed:	55                   	push   %rbp
      4004ee:	48 89 e5             	mov    %rsp,%rbp
    /mnt/hgfs/vm_share/cpp/main.cpp:4
      4004f1:	48 c7 45 f8 00 00 00 	movq   $0x0,-0x8(%rbp)
      4004f8:	00 
    /mnt/hgfs/vm_share/cpp/main.cpp:5
      4004f9:	48 8b 45 f8          	mov    -0x8(%rbp),%rax
      4004fd:	c7 00 01 00 00 00    	movl   $0x1,(%rax)
    /mnt/hgfs/vm_share/cpp/main.cpp:6
      400503:	b8 00 00 00 00       	mov    $0x0,%eax
    /mnt/hgfs/vm_share/cpp/main.cpp:7
      400508:	5d                   	pop    %rbp
      400509:	c3                   	retq   
      40050a:	66 0f 1f 44 00 00    	nopw   0x0(%rax,%rax,1)
    
    /mnt/hgfs/vm_share/cpp/main.cpp:5
      4004f9:	48 8b 45 f8          	mov    -0x8(%rbp),%rax
      4004fd:	c7 00 01 00 00 00    	movl   $0x1,(%rax)
    

    由此可以确定段错误在main.cpp的第5行*ptr = 1;

    如果是非调试版本,则需要通过汇编来确定代码位置。

    3.3 catchsegv

    catchsegv命令专门用来扑获段错误,它通过动态加载器(ld-linux.so)的预加载机制(PRELOAD)把一个事先写好的库(/lib/libSegFault.so)加载上,用于捕捉断错误的出错信息。

    $ catchsegv ./main
    *** Segmentation fault
    Register dump:
    
     RAX: 0000000000000000   RBX: 0000000000000000   RCX: 0000000000400510
     RDX: 00007fff5e1dfed8   RSI: 00007fff5e1dfec8   RDI: 0000000000000001
     RBP: 00007fff5e1dfde0   R8 : 00007fe2e3dd8e80   R9 : 0000000000000000
     R10: 00007fff5e1dfbc0   R11: 00007fe2e3a3cb10   R12: 0000000000400400
     R13: 00007fff5e1dfec0   R14: 0000000000000000   R15: 0000000000000000
     RSP: 00007fff5e1dfde0
    
     RIP: 00000000004004fd   EFLAGS: 00010246
    
     CS: 0033   FS: 0000   GS: 0000
    
     Trap: 0000000e   Error: 00000006   OldMask: 00000000   CR2: 00000000
    
     FPUCW: 0000037f   FPUSW: 00000000   TAG: 00000000
     RIP: 00000000   RDP: 00000000
    
     ST(0) 0000 0000000000000000   ST(1) 0000 0000000000000000
     ST(2) 0000 0000000000000000   ST(3) 0000 0000000000000000
     ST(4) 0000 0000000000000000   ST(5) 0000 0000000000000000
     ST(6) 0000 0000000000000000   ST(7) 0000 0000000000000000
     mxcsr: 1f80
     XMM0:  00000000000000000000000000000000 XMM1:  00000000000000000000000000000000
     XMM2:  00000000000000000000000000000000 XMM3:  00000000000000000000000000000000
     XMM4:  00000000000000000000000000000000 XMM5:  00000000000000000000000000000000
     XMM6:  00000000000000000000000000000000 XMM7:  00000000000000000000000000000000
     XMM8:  00000000000000000000000000000000 XMM9:  00000000000000000000000000000000
     XMM10: 00000000000000000000000000000000 XMM11: 00000000000000000000000000000000
     XMM12: 00000000000000000000000000000000 XMM13: 00000000000000000000000000000000
     XMM14: 00000000000000000000000000000000 XMM15: 00000000000000000000000000000000
    
    Backtrace:
    /mnt/hgfs/vm_share/cpp/main.cpp:5(main)[0x4004fd]
    /lib64/libc.so.6(__libc_start_main+0xf5)[0x7fe2e3a3cc05]
    ??:?(_start)[0x400429]
    ...
    

    License

    License under CC BY-NC-ND 4.0: 署名-非商业使用-禁止演绎

    如需转载请标明出处:http://blog.csdn.net/itas109
    QQ技术交流群:129518033


    Reference:
    NULL

    展开全文
  • 我尝试编译该程序,但编译器收到一条消息,提示"分段错误(内核已转储)"。 谁能告诉我出什么事了吗?#include #include #include #define power(x,y) (int)pow((double)x,(double)y)/*-------------------setBits----...

    我尝试编译该程序,但编译器收到一条消息,提示"分段错误(内核已转储)"。 谁能告诉我出什么事了吗?

    #include

    #include

    #include

    #define power(x,y) (int)pow((double)x,(double)y)

    /*-------------------setBits-------------------*/

    /* A function to set the i (and following) bit(s) to be 'number'. The function takes  'number' and adds the matching powers of 2 to 'destination'. */

    void setBits(int number, int i, int *destination) {

    for( ; number!=0 ; number/=2 , i++)

    (*destination) += (number % 2) * (power(2, i));

    }

    /*-------------------getDigit-------------------*/

    /* A function that returns a string of 'number' converted to base 32. */

    char getDigit(int number) {

    char *digits ="0123456789ABCDEFGHIJKLMNOPQRSTUV";

    return digits[number];

    }

    /*-------------------get32-------------------*/

    /* A function that returns a string of 'number' converted to base 32. */

    char *get32(int number) {

    char *result ="";

    if (number/32 == 0)

    result[0] = getDigit(number);

    else strcat(result,get32(number/32));

    return result;

    }

    /*-------------------main-------------------*/

    int main(){

    int test = 0;

    setBits(23, 5, &test);

    printf("%s", get32(test));

    return 0;

    }

    另外,如果有人有更好的代码提示,我也很乐意获得建议(:

    谢谢。

    请确认编译和链接阶段都可以,但是当您尝试运行它时,导致的二进制崩溃。

    char *result =""这将创建一个指向只读存储器的指针。 您不能使用strcat对其进行追加,因为修改此字符串将导致不确定的行为,在您的情况下为分段错误。

    重新安装操作系统和编译器。

    用C处理字符串很棘手。您无法像使用脚本语言一样轻松地拆分和连接它们。字符串是字符数组,其存储必须由用户处理。这也是造成分段违规的原因:您尝试修改只读内存。

    其他答案建议使用malloc。这是一种获取内存以容纳strig的可行方法,但它有一个缺点:必须释放内存。这意味着您不能直接在printf中使用get32的返回值,因为您必须将分配的字符串的句柄保留在某个地方。

    这也意味着您的递归解决方案不适合C,因为您必须free所有中间字符串。

    在您的情况下,您需要的字符串很短。您希望以32为基数打印一个32位数字。该数字最多可以包含7位数字,因此需要八个字节。 (第八个字节用于存储终止空字符。)

    另一种不使用分配的有用方法是传入一定长度的缓冲区并让函数填充它。该函数必须接收数组及其长度作为参数:

    char *get32(char buf[], int len, int number)

    {

    const char *digits ="0123456789ABCDEFGHIJKLMNOPQRSTUV";

    int n = len;

    buf[--n] = '\\0';

    memset(buf, '0', n);

    while (number) {

    buf[--n] = digits[number % 32];

    number /= 32;

    }

    return &buf[n];

    }

    此函数写入一个具有len - 1位的数字,最初全为零,然后返回一个指向第一个非零数字的指针,以便可以打印它。 char缓冲区由调用函数提供:

    int main()

    {

    int test = 0;

    char buf[8];

    setBits(23, 5, &test);

    puts(get32(buf, sizeof(buf), test));

    return 0;

    }

    当然,如果要在同一printf中打印两个数字,则必须使用不同的缓冲区,否则缓冲区将被覆盖。

    非常感谢,这对我有很大帮助!

    您需要为结果分配内存。加

    #include

    并将结果声明更改为

    char *result = calloc( BUFSIZE, sizeof(char));

    其中BUFSIZE是最大长度结果,可以将结尾的'\ 0'加一。 calloc()用零填充已分配的内存,因此您的结果字符串将正确终止。

    为了避免内存泄漏,您还应该在每次调用get32()之后释放缓冲区:

    char *result = get32(...)

    printf("%s", result);

    free(result);

    在main()中,同样在get32()本身调用之后。

    您的错误在这里:

    char *result ="";

    strcat(result,get32(number/32));

    man strcat将确认您第一个期望的参数是写入结果字符串的目标位置。由于您将result作为目标,因此strcat()将尝试写入result。不幸的是,该指针指向二进制程序的特殊目标,在该目标中注册了其文字字符串(此处为"")。本部分是只读的。

    strcat()尝试写入只读节=> BOOM => SIGSEGV。

    您应该为result分配(malloc())内存并使用strncat():

    char* const result = malloc(SOME_SIZE*sizeof(char));

    result[0] = '\\0';

    strncat(result, get32(number/32), SOME_SIZE);

    最后,不要忘记free(result);)。

    ...并且我是否强制malloc返回?

    @LPs man strcat:"与strcat()一样,dest中生成的字符串始终以空值结尾。" 但是+1演员。

    ..但是src不在您的情况下。 另请注意,sizeof(result)在您的strncat中是错误的:它将返回char *的大小,主要是4或8。

    我不想打扰您,但这不是正确的解决方案。 您可以更正get32以返回NULL终止的字符串,或使用calloc

    展开全文
  • 段错误核心已转储)的问题原因

    千次阅读 2022-02-14 22:43:54
    一个困扰久的问题,今天终于明白了。 core,核心(线圈),没有半导体之前,...往往需要使用gdb工具查看核心转储文件,且需要采用一些设置保障核心文件能够被储存,方法如下: [Linux] 什么是 段错误(吐核)

    一个困扰已久的问题,今天终于明白了。

    core,核心(线圈),没有半导体之前,使用线圈内存,指代内存。

    可执行文件是分段存储的,加载进内存也是分段的,如代码段、数据段、堆、栈等,段错误的原因往往是碰到了不该碰到的内存位置(如系统保留段、代码段不能被修改,使用空指针等)。

    核心已转储就是说进程结束之前,内存已被储存,可以用于程序员翻看程序的“临终遗言”来定位问题。往往需要使用gdb工具查看核心转储文件,且需要采用一些设置保障核心文件能够被储存,方法如下:

    [Linux] 什么是 段错误(吐核)?_giturtle's blog-CSDN博客_段错误(吐核)

    已经设置了ulimit,为什么还是没有core文件 - 菜鸡徐思 - 博客园

    展开全文
  • Linux上如何得到一个段错误核心转储 文章目录什么是段错误?步骤1:运行 valgrind如何获得一个核心转储ulimit:设置核心转储的最大尺寸kernel.core_pattern:核心转储保存在哪里kernel.core_pattern 和 Ubuntu...
  • gdb使用core文件调试程序,解决“段错误核心已转储“的问题;设置core文件开关,解决> "警告:此文件自读入后发生改动!!!"以及"core pattern" E667:同步失败的信息;等问题
  • 段错误一般就是指访问的内存超出了系统所给这个程序的内存空间,通常这个值是由gdtr来保存的,他是一个48位的寄存器,其中的32位是保存由它指向的gdt表,后13位保存相应于gdt的下标,最后3位包括了程序是否在内存中...
  • Ubuntu20.04出现段错误核心已转储问题解决方案

    千次阅读 多人点赞 2022-04-01 16:05:44
    ubuntu 20.04出现段错误核心已转储,使用GDB测试找不到core文件解决方案
  • Ubuntu18.04系统安装cuda时,发生s段错误 (核心已转储)的解决记录。
  • Linux段错误核心已转储

    千次阅读 2019-09-29 08:42:00
    最近一个代码编译之后,运行老是报“段错误核心已转储”,用gdb的bt命令也无法定位到原因。最后发现是因为一个返回int类型的函数没有写return。windows下面没有return的会自己return,linux下编译警告没有return,...
  • 解决Linux c语言运行时候“段错误 (核心已转储)”问题-采用gdb 解决
  • 对报错:段错误 (核心已转储)的理解
  • ubuntu段错误核心已转储

    万次阅读 2018-04-03 16:03:59
    core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump. (linux中如果内存越界会收到SIGSEGV信号,然后就会core dump)在程序运行的...
  • 显示段错误核心已转储怎么解决呢,用了很多种方法都解决不了,有没有谁会啊
  • Linux服务器上训练模型时,每当训练数据时程序就会自动停掉,报段错误核心已转储),经过搜索有人说是程序越界了,stack太小了,于是我用ulimit -a 查看了Linux中stack的大小,然后又使用ulimit -c 10240修改...
  • 编程实现生产者和消费者共享存储区功能。生产者随机产生10个整型数据,写入共享存储区;消费者读出数据,并进行平方和平方根运算后输出。使用系统调用shmget()、shmat()、sgmdt()、shmctl()等, 实现程序。...
  • c++如何解决段错误 (核心已转储)

    千次阅读 2021-06-18 17:35:26
    在后端优化中遇到了段错误 (核心已转储)问题,寻求解决方法。 首先通过不断的注释部分代码,运行,注释,运行,找到一个大概的范围是错在哪一块。 这类问题只能说根本原因是内存的非法操作。建议生成内存段错误转储...
  • 试了很多办法都没生成core文件,我用是ubuntu系统做了一下两条就在当前目录下生了core文件,然后就可以使用gdb调试1、ulimit -c filesize,修改core文件的大小,可以先用ulimit -a 查看core file size 对应的值2、...
  • This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: . Find the GDB manual and other documentation resources...
  • 今天在研究linux kernel中typedef的用法时,写了一个程序test_typedef.c,内容如下: #include<stdio.h> typedef int size; typedef unsigned int word; typedef char line[81]; typedef void (*printStr)...
  • 如果这样写的话编译会出现段错误核心已转储)问题。 解决方法: 用malloc开辟空间就行,c++中用new 例如定义一个3000*3000的矩阵 #include<stdio.h> #define N 3000 int main() { int **arr1; arr1...
  • 在服务器上(环境Linux)运行代码,出现段错误核心已转储错误。 在Pycharm直接运行艾玛(环境Linux),出现Process finished with exit code 139错误。 找了好几个博客,都是说,段错误是内存访问越界,主要是...
  • 记录一下今天在使用虚拟机搭建环境时遇到的问题 ...在安装的过程中一直出现“段错误 (核心已转储) ”,在网上找了教程之后发现通过: // 详见conda命令用法 conda clean -a 来清理之后重新安装可以解决。其原
  • 每次单目运行10s左右,双目1-2s时VINS的VINS_Node节点便会出现“断错误(核心已转储)”导致程序中断,其他RVIZ和数据发送节点都正常。问题解决路径:1、起初在网上查询段错误的解决方法,大部分都指明与内存有关,尤其...
  • linux系统“s段错误 (核心已转储)“错误解决的解决

    千次阅读 热门讨论 2020-02-01 11:18:08
    s段错误 (核心已转储)错误解决 下载cuda时,下载地址 wget http://developer.download.nvidia.com/compute/cuda/10.2/Prod/local_installers/cuda_10.2.89_440.33.01_linux.run 时到99%报错 “剩余 2s s段错误 (核心...
  • 在主脚本调用其他脚本,且主脚本和调用脚本都使用到了cv2.VideoCapture(0)。...出现如下错误: 解决方法:只使用一次VideoCapture() 主脚本和副脚本之间用形参传递 结果:成功解决问题 ...
  • 通过使用ZED2相机建立的地图,地图重载时出现这个问题。 ... 错误定位到Map.cc中加载关键帧的地方。...段错误(核心已转储)应该不止这个加载地图的时候会出去,之前也在其他地方见到过这个错误。</p>
  • 文章目录前言一、解决办法二、问题原因总结 前言 提示:以下是本篇文章正文内容,下面案例可供参考 一、解决办法 重装anaconda3 二、问题原因 可能是某一个正在运行的程序导致了这个问题 ,我也没搞明白 。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,459
精华内容 3,383
关键字:

linux段错误核心已转储

友情链接: fnggre.rar