转自:http://bbs.chinaunix.net/thread-1685440-1-1.html
很多程序员都遇到过这样的问题:已经上线运行很长时间的系统出了问题,并且其中的很多程序经过了多次的修改和升级,日志中的信息和现有的程序完全对不上号!怎样才能查看程序的信息(例如版本号、编译的时间等)、以确定程序的确切版本呢?很多的版本管理工具(例如CVS、SVN)可以帮你管理源码的版本,但并不会在编译的时候把编译信息写到二进制执行码中去。因此,还是要通过其他手段来实现。
在这里我提供了一种在可执行程序中写入编译信息的办法,希望对大家有帮助。
这个例子由两个程序构成:test.c、version.c。其中version.c用于实现编译信息的记录,只要在现有的代码中加入该程序,而不需要对已有代码作任何的修改,就能实现二进制执行码的版本信息管理。
version.c
- #include
- /* 以下两个宏用于在编译时通过宏定义传入编译信息
- VERSION被替换为const char version[]=”Resivion: xxxx”
- BUILDTIME被替换为 const char buildtime[]=”Buildtime: yyyymmdd”
- */
- VERSION;
- BUILDTIME;
- void print_version()
- {
- printf( “%s\n”, version );
- }
- void print_buildtime()
- {
- printf( “%s\n”, buildtime );
- }
print_version()和print_buildtime()这两个函数不是必须的,只是让version.c看起来“更象个程序”,同时可以提供在外部程序中输出编译信息的手段。
test.c
- #include
- int main()
- {
- print_version();
- print_buildtime();
- }
在test.c中调用这两个函数只是用于测试,正式版本的程序中可以用实际的代码替换。
在Makefile中添加以下的内容:
- version="const char version[]=\"Revision: 1.2.2\""
- buildtime="const char buildtime[]=\"Buildtime: `date +%Y%m%d`\""
- CFLAGS=-c –g –DVERSION=”$version” –DBUILDTIME=”$buildtime”
- testversion: test.o version.o
- cc –o $@ $?
- .c.o :
- $(CC) $(CFLAGS) $<
如果你使用了版本管理工具,可以通过工具动态读取版本(或修订)信息,将信息赋值给version变量。你完全可以自己定义宏定义的格式,例如将编译的精确时间写进去。
编译后执行:
- $testversion
- Revision: 1.2.2
- Buildtime: 20100402
- $
通过strings命令查看:
- $string testversion | grep Revision
- Revision: 1.2.2
- $strings testversion | grep Buildtime
- Buildtime: 20100402
这个结果是我真正希望的!只要通过查看二进制执行码中的字符串,就可以确定程序的版本了!
分享到:
相关推荐
2. **预处理**:预处理器(Preprocessor)处理宏定义、条件编译指令等。 3. **编译**:编译器将预处理后的代码转换为汇编代码。 4. **汇编**:汇编器将汇编代码转化为机器码。 5. **链接**:链接器(Linker)将多个...
实验内容涉及ASCII码、BCD码、二进制机器码、ASCII码和七段显示码之间的转换。通过理解这些转换关系,学习者可以编写程序实现数制转换,并使用示波器等工具进行程序的调试。 在这个实验中,学习者会遇到如何将...
IBM大型机汇编语言中可以通过`.BYTE`指令来定义二进制数,例如`.BYTE 2'B11010110`表示定义一个字节的二进制值为`11010110`。 **1.3.3 逻辑数** 逻辑数通常指的是布尔值或位字段。IBM大型机汇编语言提供了多种指令...
3. **预处理**:某些汇编语言支持预处理器指令,如宏定义或条件编译。在这个阶段,汇编器会处理这些指令,对源代码进行相应的扩展或修改。 4. **指令编码**:对于某些汇编器,第一遍可能还包括初步的指令编码,将非...
它能够解析源代码,理解助记符的含义,并生成相应的二进制指令,这对于理解和调试汇编代码大有裨益。 其次,程序地址分配是另一个核心功能。在编译过程中,每个指令和数据都需要在内存中占据一个特定的位置。文本...
- `MovToVar` 是一个宏定义,用于将寄存器的内容移动到指定的变量。宏在编译时会被展开,节省重复编写代码的时间。 2. **数据段(Data Segment)**: - `data segment` 定义了一个数据段,其中包含了多个双字节...
预处理主要处理#include指令、宏定义以及条件编译等;编译阶段将源代码转换成汇编代码;汇编阶段将汇编代码转换为机器码;链接阶段则将各个编译后的目标文件整合成可执行程序。 在《C语言程序设计案例教程》中,源...
2. 文件操作:在C语言中,对二进制文件进行追加操作需要使用"ab"模式,如题目2所示,而"D"选项的"wb+"会在写入前清空文件,因此不是追加。 3. 字符编码与输出:题目3考察了字符编码,'a'到'h'的ASCII码差值为1,...
- 十六进制数88H可转换为无符号十进制数136,压缩型BCD码的十进制数88,但不能表示为-120(负数)或8位二进制数-8的补码。 11. **寻址与存储**: - 指令指针寄存器IP用于存放下一条指令的偏移地址。 - CS(Code ...
可以通过 `PreparedStatement` 设置二进制流参数,并执行插入操作。 - **读取BLOB数据**:从数据库中读取BLOB数据时,可以通过 `ResultSet` 获取二进制流,并将其保存到文件或其他介质中。 - **获取元信息**:使用...
汇编器是将人类可读的汇编语言代码转换成机器可执行的二进制代码的关键工具。 在6502汇编语言中,程序员编写的一系列指令和伪指令与6502微处理器的机器码相对应。这些指令包括数据处理(如加法、减法)、转移控制...
- BIN文件:这是一种二进制文件,包含了机器码,可以直接写入单片机中执行。 - HEX文件:由INTEL公司定义,以ASCII码存储地址、数据和校验码,便于显示和打印,并且通常通过符号转换程序(如OHS51)转换。 2. **...
其主要任务是将汇编语言程序转换为机器可执行的二进制代码。 2. **源代码结构** NASM 0.98的源代码包含多个组件,每个组件都有特定的职责: - `nasm.c`:这是NASM的主要入口点,负责处理命令行参数,初始化编译...
- 高级语言如Java、Python等,更接近人类自然语言,需要编译或解释才能被执行。 **3. 形码与自然码、五笔字型、大众码** - 形码根据字形结构编码。 - 自然码和五笔字型属于形码。 - 大众码不是形码。 **4. ...