您的位置:首页 > 大数据 > 人工智能

解决错误:Assertion failed: hunk, file patch.c, line 321

2015-04-15 14:48 465 查看
问题阐述:

最近在windows上做一个开源包的build工作,需要打patch,patch文件通过diff命令生成的,使用参数(Options)为-Naur。但是当我在windows的command prompt(有安装cygwin)下做的时候先后报出如下错误:

1.Assertion failed: hunk, file patch.c, line 321 但是操作目录文件夹下没有patch.c文件。

2.patching
file `mspack\system.h'

Hunk #1 FAILED at 10.
Hunk #2 FAILED at 43.
Hunk #3 FAILED at 59.

3 out of 3 hunks FAILED


上网查了一下,顺便给自己做个总结:

背景调查:

大多数的LINUX/UNIX操作系统,比如ubuntu, suse,centos,都使用LF(linefeed)做为行尾符(line ending),即就是'\n',ASCII 码是10,用十六进制表示为0x0A;

微软的Windows例外,Windows中要加回车键CRLF(carriage return followed by a linefeed ),即就是'\r\n',ASCII码分别是 13 10,用十六进制表示为0x0D,0x0A,相信有过在windows上调试串口UART的人经常看到0x0d,0x0a;

MacOS采用回车符CR(carriage return)作为行尾符'\r', ASCII码值是13,用十六进制表示为0x0D。

所以在unix操作系统下打的patch直接在windows的dos环境下是用不成的,这样会报出第一个错误:Assertion
failed: hunk, file patch.c,line 321
实际上并不一定存在patch.c文件。

第二个错误上网查询说大部分是路径不对或者patch文件本身有问题导致的,当时仔细看了应该觉得路径什么的都对,只是注意到patch文件中的目录层级划分使用的是windows风格,类似于:C:\Program
Files (x86)\VMware\VMware Workstation\x64\file.patch, 而linux中的目录划分是类似于:/home/brandon/data/source/path/to/dir/file.patch。注意字符'\' 和字符'/'的区别。这样如果在linux下打patch,就会把整个路径当成一个字符串处理“C:\Program
Files (x86)\VMware\VMware Workstation\x64\file”,而不是真的按照原来的在C盘目录下找VMware文件夹,再在该文件夹下找VMware Workstation文件夹, 在该目录下找到x64文件夹,最后找到file文件并且打patch。

References:
http://www.microhowto.info/howto/convert_the_line_endings_in_a_text_file_from_unix_to_dos_format.html http://www.microhowto.info/howto/convert_the_line_endings_in_a_text_file_from_dos_to_unix_format.html http://stackoverflow.com/questions/14282617/hunk-1-failed-at-1-whats-that-mean
解决方案:

大概做了一些背景调查后,我开始去解决问题,修改了编译脚本,提交代码,让jenkins去build。由于公共的jenkins机器里面有很多编译包,所以跑起来很慢,差不多6,7个小时才能跑完一次,上班也就只能看到一次结果,修改后只能等第二天查看结果。所以我自己搭建了一台环境,是克隆的jenkins Windows编译环境,vmware的vcenter确实很好用。可是我这边的跑过了,但是jenkins就是跑不过,到我提交的那个包就出错,折腾了好几天...

为了搞清楚我在windows下和linux下都有尝试去复现问题。

第一个错误比较简单, 用了todos命令将patch文件从unix 格式转换成dos格式,打patch时加了参数"--binary",fix了这个bug,没有再报Assertion failed的错误,其实还有很多方法可以解决line endings的问题,比如用unix2dos,sed命令等,相应的还有dos2unix命令,fromdos命令。要使用todos命令,需要先安装 tofrodos包,tofrodos安装包和unix2dos安装包在debian-based系统下的安装:

brandon$sudo apt-get install
tofrodos


brandon$sudo apt-get install dos2unix

brandon$

brandon$todos -h

tofrodos Ver 1.7.8 Converts text files between DOS and Unix formats.

Copyright 1996-2008 by Christopher Heng. All rights reserved.

Usage: todos [options] [file...]

-a Always convert (DOS to Unix: kill all CRs;

Unix to DOS: convert all LFs to CRLFs)

-b Make backup of original file (.bak).

-d Convert DOS to Unix.

-e Abort processing files on error in any file.

-f Force: convert even if file is not writeable.

-h Display help on usage and quit.

-l file Log most errors and verbose messages to <file>

-o Overwrite original file (no backup).

-p Preserve file owner and time.

-u Convert Unix to DOS.

-v Verbose.

-V Show version and quit.

brandon$

brandon$

brandon$fromdos -h

tofrodos Ver 1.7.8 Converts text files between DOS and Unix formats.

Copyright 1996-2008 by Christopher Heng. All rights reserved.

Usage: fromdos [options] [file...]

-a Always convert (DOS to Unix: kill all CRs;

Unix to DOS: convert all LFs to CRLFs)

-b Make backup of original file (.bak).

-d Convert DOS to Unix.

-e Abort processing files on error in any file.

-f Force: convert even if file is not writeable.

-h Display help on usage and quit.

-l file Log most errors and verbose messages to <file>

-o Overwrite original file (no backup).

-p Preserve file owner and time.

-u Convert Unix to DOS.

-v Verbose.

-V Show version and quit.

brandon$

brandon$todos -d -f /path/to/file.patch

brandon$patch -p1 < ../need-file.patch --binary

一共有两个patch文件,jenkins跑的时候打第一个patch没问题,但是打第二个patch就会报第二个错误,去看脚本代码都是执行了todos命令的:


for p in `ls | grep patch`

do

todos -f $p

done

很奇怪第二个脚本一直报 hunks FAILED的错误。在自己克隆的机器上是能跑的过得,但是当我执行这个命令:todos -u -f /path/to/file.patch,就会报这个错误,只带-f参数或者-d -f就可以顺利通过,所以最后又在打patch之前又执行了一次“todos -d -f /path/to/file2.patch”
然后执行“patch -p1 < ../file2.patch --binary”最后顺利通过。

这里有些不理解的是,脚本里已经有了对patch文件的todos命令了,而且第一个file1.patch顺利跑过但是但是第二个patch文件为什么默认执行的是"todos -u -f file2.patch"命令。在linux下我是在vim中输入:%s/\\/\//g将patch文件中的字符‘\’替换成'/'的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: