zoukankan      html  css  js  c++  java
  • 记录一个glibc 导致的段错误以及gdb 移植

    • 上一篇我有相关关于一个段错误的记录,现在记录当时的段错误具体是在哪里的。

        // 从 GNU 的官网下载当前在使用的 glibc 的源代码以及最新的 glibc 源代码
        //  地址如下: http://ftp.gnu.org/gnu/libc/
        //  下载的是 glibc-2.12.2.tar  以及最新的 glibc-2.25.tar 两个版本
        //   这里要记住, glibc 2.12.2 这个版本是有一个bug 的,  times 的参数不能传 NULL。
    
        //  解压  glibc-2.12.2.tar  
        tar  -xvf  glibc-2.12.2.tar.gz
        cd   glibc-2.12.2
        vim sysdeps/unix/sysv/linux/times.c
    
        // 这个文件中的一段代码会导致程序调用了 times 运行一段时间后会产生段错误
        clock_t                                                                         
        __times (struct tms *buf)                                                       
        {                                                                               
          INTERNAL_SYSCALL_DECL (err);                                                  
         clock_t ret = INTERNAL_SYSCALL (times, err, 1, buf);                          
          if (INTERNAL_SYSCALL_ERROR_P (ret, err)                                       
              && __builtin_expect (INTERNAL_SYSCALL_ERRNO (ret, err) == EFAULT, 0))     
            {                                //   这里如果传的 buf == NULL 的话,也会执行里面的操作。                                           
              /* This might be an error or not.  For architectures which have           
             no separate return value and error indicators we cannot                    
             distinguish a return value of -1 from an error.  Do it the                 
             hard way.  We crash applications which pass in an invalid BUF                 
             pointer.  */                                                               
        #define touch(v)                                                               
              do {                                                                     
            clock_t temp = v;                                                          
            asm volatile ("" : "+r" (temp));                                           
            v = temp;                                                                  
              } while (0)                                                               
              touch (buf->tms_utime);
               // 如果是 NULL->tms_utime 可能在运行一段时候后产生段错误 
              touch (buf->tms_stime);                                                   
              touch (buf->tms_cutime);                                                  
              touch (buf->tms_cstime);                                                  
                                                                                    
              /* If we come here the memory is valid and the kernel did not             
             return an EFAULT error.  Return the value given by the kernel.  */         
            }                                                                           
                                                                                    
          /* Return value (clock_t) -1 signals an error, but if there wasn't any,       
             return the following value.  */                                            
          if (ret == (clock_t) -1)                                                      
            return (clock_t) 0;                                                         
                                                                                    
         return ret;                                                                   
        }                                                                                                                       
    
        //  对比了最新版的 glibc , 他已经修改了对应的代码
         28   if (INTERNAL_SYSCALL_ERROR_P (ret, err)                                       
         29       && __builtin_expect (INTERNAL_SYSCALL_ERRNO (ret, err) == EFAULT, 0)      
         30       && buf)      
        //  这里对 buf 进行了判断, 如果为 buff 为真才进去。
    
    • 目前我的解决方式是用 以前交叉编译器里面的的glibc.so.6 , 暂时运行还未出现问题。

    • 但是使用了之前的 glibc 之后,发现 gdb 不能使用,所以又将 gdb 用以前的交叉编译器编译了一次。

    • 过程如下:

        //  第一步是下载 gdb 的源码以及 ncurses 的源码 以及 termcap 的源码
        gdb 下载地址  :  http://ftp.gnu.org/gnu/gdb/
        gdb  我是下载了一个比较保守的版本  7.2 ,我怕比较新的有问题。
        
        ncurses 下载地址:  http://ftp.gnu.org/pub/gnu/ncurses/ncurses-5.8.tar.gz
        termcap 下载地址:  http://ftp://ftp.gnu.org/gnu/termcap/termcap-1.3.1.tar.gz
    
    • 解压相关源代码

        tar -xvf termcap-1.3.1.tar.gz
        tar -xvf gdb-7.2a.tar.bz2
    
    • 交叉编译 termcap

        cd termcap-1.3.1/
        mkdir output
        vim my.sh
        #!/bin/sh                                                                       
                                                                                    
        ./configure --target=arm-none-linux-gnueabi --prefix=/home/sbc_7816_sdk6/test/gdb/termcap-1.3.1/output
    
        chmod +x my.sh
        ./my.sh
        make
        make install
    
        将 output/lib  下面的库copy 到交叉编译器的  lib 里面, include  也是
        cp output/lib/libtermcap.a  /home/sbc_7816_sdk6/aplex/linux-devkit/usr/local/arm/4.3.2/arm-none-linux-gnueabi/lib
        cp output/include/termcap.h   /home/sbc_7816_sdk6/aplex/linux-devkit/usr/local/arm/4.3.2/arm-none-linux-gnueabi/include/  
    
    • 交叉编译 gdb

        cd ~/test/gdb/gdb-7.2/
        mkdir output
        vim my.sh
        #!/bin/sh                                                                       
                                                                                    
        ./configure --target=arm-linux --host=arm-linux --prefix=/home/sbc_7816_sdk6/test/gdb/gdb-7.2/output
    
        chmod +x my.sh
        ./my.sh
        make
        make install 
    
         将生成的 output/bin  里面的 gdb  gdbserver  拷贝到 目标文件系统的  /usr/bin 下面,要覆盖
    
        完成
    
  • 相关阅读:
    FPGA之verilog流水灯小程序
    FPGA之Verilog点灯小程序
    FPGA学习入门
    机试题 (用 hash 实现部门管理系统 只记得大概的内容,简洁版) -- 上一篇的优化
    机试题 (用 hash 实现部门管理系统 只记得大概的内容,简洁版) --> 这里改成文件管理系统
    双向循环链表 (只需要一个 head 节点), 从头尾部 删除 插入 数据都比较方便
    使用 head + tail 两个头尾节点实现双向链表 (队列太多会占用内存), 数据的添加删除比较方便
    线程学习
    堆排序演示 ( 这个 堆排函数将适合所有的堆排, 只需要改一下比较函数)
    windows10 下访问 virtualbox 虚拟机的linux15.10/16.04 系统 及 用 putty 访问虚拟机的配置
  • 原文地址:https://www.cnblogs.com/chenfulin5/p/7133449.html
Copyright © 2011-2022 走看看