使用strings工具判断软件版本与core dump文件的版本是否一致

在Linux下开发程序时,经常会遇到内存访问错误而产生core dump文件。在使用gdb来debug时,需要保证软件版本与core dump文件的版本保持一致。但是在开发过程尤其是大型软件的开发过程中,由于版本的频繁发布以及开发和测试的分工,搞错版本是经常遇到的事。


本文介绍一种判断版本是否一致的简单方法。主要利用了strings工具提供的字符串提取功能。
注:这个想法是从一位同事那了解到的,我只不过写了个程序和脚本验证了一下

【主要思想】
在某个C文件中定义一个保存了版本信息的全局字符串变量,例如unsigned char version[] = "Version_V1R1C00"。这个全局变量只用于保存版本信息,并需要保证程序中不会存在类似的字符串(至少前几个字符不一样)。这样在软件版本和core dump文件中就会保存这个版本字符串信息。使用strings工具将这些信息提取出来并加以比较,就可以确定版本是否一致了。
 
注意:每发布一个版本,需要相应地修改这个全局变量。

【简要说明】
(1)Linux下的C程序常常会因为内存访问出错而造成segment fault等错误,如果此时系统的core dump功能是打开的,则会将程序运行出错时的内存映像存储到硬盘上,接着就可以使用gdb对core dump文件进行分析。

Linux系统默认不打开core dump功能,可以使用ulimit -c命令判断或打开core dump功能。




(2)strings工具
功能:打印文件中(如非文本文件)的可打印字符串。默认情况下,字符串至少需要包含4个字符,但可以通过-n选项配置字符串的最小长度。
用法:man strings或google一下

(3)脚本中使用printf进行格式化输出:脚本使用“ANSI非常规字符序列”来设置shell脚本输出的字体和颜色,如出错则打印信息为”红色“,结果正确则打印信息为”绿色“。
用法:见”设置shell脚本输出字体颜色“。链接为http://biancheng.dnbcw.info/shell/234763.html

【脚本文件】
VersionMatch.sh

#!/bin/sh

# 判断输入是否正确
if [ $# -ne 2 ]; then
    printf "\033[31merror: The right format is <SCRIPT_NAME SOFT_NAME CORE_NAME>\033[0m\n"
    exit 1
fi

if [ ! -f $1 ]; then
    printf "\033[31merror: $1 doesn't exist or is not a regular file.\033[0m\n"
    exit 1
fi

if [ ! -f $2 ]; then
    printf "\033[31merror: $2 doesn't exist or is not a regular file.\033[0m\n"
    exit 1
fi

# 获取版本信息
SOFT_VER=$(strings $1 | grep Version)
CORE_VER=$(strings $2 | grep Version)

# 获取输入文件名的字符串长度
LEN_SOFT=$(expr length $1)
LEN_CORE=$(expr length $2)

if [ $LEN_SOFT -ge $LEN_CORE ]; then
    LEN=$LEN_SOFT
else
    LEN=$LEN_CORE
fi

# 格式化输出:保证对齐
printf "%-$(($LEN))s: $SOFT_VER\n" $1
printf "%-$(($LEN))s: $CORE_VER\n" $2

# 比较版本信息
if [ "$SOFT_VER" = "$CORE_VER" ]; then
    printf "\033[32mmatch!\033[0m\n"
else
    printf "\033[31mWaring: not match!!!\033[0m\n"
fi

exit 0

【举例说明】
(1)定义一个C文件,主要代码如下。由于访问了非法地址,运行时会生成一个coredump文件。
#include <stdio.h>

unsigned char version[] = "Version_V1R1C00";

int main()
{
    int *a = NULL;
    int b = *a; 
    return 0;
}

(2)假设生成的软件为a.out,生成的core dump文件为core
在shell下执行会看到输出结果为。(注:这里只是介绍一下strings的用法,与脚本无关)

(3)在shell下执行VersionMatch.sh,可看到如下结果:



如果将version的值改为"Version_V1R2C00",重新生成a.out,但不执行a.out,即不重新生成core。则执行结果如下:



【使用总结】
简单总结下使用方法:(1)定义一个全局变量保存版本信息;(2)将脚本中SOFT_VER=$(strings $1 | grep Version)和CORE_VER=$(strings $2 | grep Version)这两行的Version改为全局变量中前几个不会变化的字符。

strings.com 是强大的纯DOS环境 下的文本处理工具 STRINGS常用方法: 1、把文本文件 LIST.TXT 包含的行数赋值给变量 LN STRINGS LN=LINESIZE LIST.TXT 2、把文本文件 LIST.TXT 的大小传递给变量FS STRINGS FS=FILESIZE LIST.TXT 3、读取文本文件 LIST.TXT 的第5行内容并赋值给变31333137量 LN STRINGS LN=READ LIST.TXT,5 4、把变量 N 在原有基础上+1 和 -1 STRINGS N=ADD %N%,1 STRINGS N=SUB %N%,1 5、把字符串 ABCDEFG 中第四个字符以及后面共3个字符传递给变量 LX (DEF) STRINGS LX=MID ABCDEFG,4,3 6、查找字符串 ABCDEFG 中D所在的位置并赋值给变量DX,如果没找到DX=0 STRINGS DX=FIND ABCDEFG,D 7、找出字符串 ABCD EFG HIJ KLMN 中第二个单词并赋值给变量L2 STRINGS L2=PARSE ABCD EFG HIJ KLMN ,2 应用举例:逐一显示文件 LIST.TXT 各行内容 @ECHO OFF REM 读取LIST.TXT大小如果是0就转入 ERROR段 STRINGS FS=FILESIZE LIST.TXT IF %FS%*==0* GOTO ERROR REM 读取 LIST.TXT 行数 并用N作计数器以循环方式显示 LIST.TXT各行内容。 STRINGS L=LINESIZE LIST.TXT STRINGS L=ADD %L%,1 SET N=0 :LOOP STRINGS N=ADD %N%,1 STRINGS LX=READ LIST.TXT,%N% ECHO %LX% IF %N%*==%L%* GOTO END GOTO LOOP :ERROR ECHO LIST.TXT IS NULL :END SET FS= SET L= SET N= SET LX= --------------------------------------------- NSET 的常用方法: 1、把某一命令的执行结果传递给变量。 A.把 DIR 命令执行结果第7行中的第2个单词传递给变量 DIRX DIR /A /S |NSET /L7 DIRX=$2 B.把当前路径传递给变量 CDX CD |NSET CDX=$0 2、获取 LIST.TXT 文件第5行第2个单词的内容并赋值给变量 L52 NSET /L5 L52=$2 <LIST.TXT 举例:显示出 LIST.TXT 文件中第二个单词是 SYSTEM 的行的内容。 @ECHO OFF REM 读取LIST.TXT大小如果是0就转入 ERROR段 STRINGS FS=FILESIZE LIST.TXT IF %FS%*==0* GOTO ERROR REM 读取 LIST.TXT 行数 并用N作计数器以循环方式显示 LIST.TXT中第二个单词是 REM SYSTEM 的行的内容,每找到一个符合条件的行,就把变量M在原有基础上+1。 STRINGS L=LINESIZE LIST.TXT STRINGS L=ADD %L%,1 SET N=0 SET M=0 :LOOP STRINGS N=ADD %N%,1 STRINGS LX=READ LIST.TXT,%N% REM STRINGS LX2=PARSE %LX%,2 NSET /L%N% LX2=$2 diskn.txt REM 如果存在DISKN2.TXT 就删除之 if exist diskn2.txt del diskn2.txt >nul REM 获取DISKN.TXT文件行数并用N做计数器逐行判断,并把需要的信息传递给DISKN2.TXT REM 如果该行前两个字符是 NO 说明没有硬盘,就退出脚本 RE
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值