成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

國外開發者:檢驗并恢復損壞的git數據文件

開發 前端
最近我提交了一分損壞的文件到資源庫上,被問到數據是否可恢復。根據提出的描述開始著手調查和修復問題,我認為其他人也會對解決的過程感興趣,或者遇到相同狀況后可以幫助到你。

最近我提交了一分損壞的文件到資源庫上,被問到數據是否可恢復。根據提出的描述開始著手調查和修復問題,我認為其他人也會對解決的過程感興趣,或者遇到相同狀況后可以幫助到你。

我開啟了檢查(fsck),發現問題出現在一個類上(我過去經常用 $pack $obj 命令使得輸出可讀,而且因為我也更傾向于他們):

  1. $ git fsck 
  2. error: $pack SHA1 checksum mismatch 
  3. error: index CRC mismatch for object $obj from $pack at offset 51653873 
  4. error: inflate: data stream error (incorrect data check) 
  5. error: cannot unpack $obj from $pack at offset 51653873 

錯誤的信息意味著一個字節在某一個地方混亂了,推測是類里面描述過的(因為檢驗和的索引和zlib都失敗了)

通過閱讀zlib源代碼,我發現“檢查不正確數據”意味著adler-32

算法檢驗zlib數據末端沒有匹配已經增加的數據。因此通過zlib壓縮數據是沒有用的,因為到每次末尾都會有錯誤,此時我們了也解到這個crc文件不能匹配。這個出錯的字節存在類文件的任何地方。

第一件事情我從packfilepull出損壞的文件。我需要知道到底它多大的類,然后我發現了下面的信息:

  1. $ git show-index <$idx | cut -d' ' -f1 | sort -n | grep -A1 51653873 
  2.   
  3. 51653873 
  4. 51664736 

Show-index命令可以列出類和他們的偏移量。我們除了偏移量以外通通拋棄,然后排列,這樣我們感興趣的偏移量(這個位置是從上面fsck命令得出來的)是遵循下一個對象的偏移量。現在我們知道類文件長度是10863字節,然后我們可以抓取它:

  1. dd if=$pack of=object bs=1 skip=51653873 count=10863 

我檢查了文件的十六進制,搜索任何明顯的錯誤(例如,一個4K大小運行中的0是文件系統沖突很好的信號)。但是所有的地方看起來都很合理。

注意到“object”文件不適合被zlib直接壓縮;它本身包含git類信息頭,而且是可變長度的。我們想要去掉它,所以開始直接使用zlib操 作數據。你可以用你手工的方式(格式化信息的描述在Documentation/technical/pack-format.txt里面),或者你也可 以用debugger搞定它。我選擇了后者,創建了一個驗證的包如下:# pack magic and version

  1. # pack magic and version 
  2. printf 'PACK\0\0\0\2' >tmp.pack 
  3. # pack has one object 
  4. printf '\0\0\0\1' >>tmp.pack 
  5. # now add our object data 
  6. cat object >>tmp.pack 
  7. # and then append the pack trailer 
  8. /path/to/git.git/test-sha1 -b <tmp.pack >trailer 
  9. cat trailer >>tmp.pack 

然后在debugger中運行”git index-pack tmp.pack” 命令(會停在unpack_raw_entry)。做到這里,我發現有3個自己的信息頭(信息頭本身有一個完整的類型和大小)。然后我用下面語句去掉了這些內容:

  1. dd if=object of=zlib bs=1 skip=3 

我用一個自定義的C程序過的zlib的解壓鎖結果。但是它報錯了,我得到準確的輸出數字字節(也就是說,它匹配了上面解碼的git的信息頭大小)。 但是”git hash-object” 命令的結果并沒有相同的shal值。所以現在仍然有一些錯誤的字節是我不知道的。這個文件發生在C源程序代碼, 我希望我能注意到一些明顯的錯誤,但是我沒有成功,我甚至都編譯成功了!

我也試過和在資源庫相同路徑下其他版本的文件作比較,希望有不一樣和不合理的部分。不幸運的是,這碰巧是唯一的修訂文件,在這個資源庫中。所以我沒有任何東西可以作比較。

于是我采取不同的措施,猜測著沖突是由限制單個字節引起的,我寫了交換每個字節的程序,是這解壓縮得到結果。因為這個類文件壓縮過后僅有10K,花了很多時間解壓出之后的結果是2.5M。

這是我用的程序:

  1. #include <stdio.h> 
  2. #include <unistd.h> 
  3. #include <string.h> 
  4. #include <signal.h> 
  5. #include <zlib.h> 
  6.   
  7. static int try_zlib(unsigned char *buf, int len) 
  8.   /* make this absurdly large so we don't have to loop */ 
  9.   static unsigned char out[1024*1024]; 
  10.   z_stream z; 
  11.   int ret; 
  12.   
  13.   memset(&z, 0, sizeof(z)); 
  14.   inflateInit(&z); 
  15.   
  16.   z.next_in = buf
  17.   z.avail_in = len
  18.   z.next_out = out; 
  19.   z.avail_out = sizeof(out); 
  20.   
  21.   ret = inflate(&z, 0); 
  22.   inflateEnd(&z); 
  23.   return ret >= 0; 
  24.   
  25. /* eye candy */ 
  26. static int counter = 0
  27. static void progress(int sig) 
  28.   fprintf(stderr, "\r%d", counter); 
  29.   alarm(1); 
  30.   
  31. int main(void) 
  32.   /* oversized so we can read the whole buffer in */ 
  33.   unsigned char buf[1024*1024]; 
  34.   int len; 
  35.   unsigned i, j; 
  36.   
  37.   signal(SIGALRM, progress); 
  38.   alarm(1); 
  39.   
  40.   len = read(0, buf, sizeof(buf)); 
  41.   for (i = 0; i < len; i++) { 
  42.     unsigned char c = buf[i]; 
  43.     for (j = 0; j <= 0xff; j++) { 
  44.       buf[i] = j; 
  45.   
  46.       counter++; 
  47.       if (try_zlib(buf, len)) 
  48.         printf("i=%d, j=%x\n", i, j); 
  49.     } 
  50.     buf[i] = c; 
  51.   } 
  52.   
  53.   alarm(0); 
  54.   fprintf(stderr, "\n"); 
  55.   return 0; 

編譯和運行的結果:

  1. gcc -Wall -Werror -O3 munge.c -o munge -lz 
  2. ./munge <zlib 

有一些錯誤出現(如果你在zlib的信息頭中得到”no data”信息,zlib認為它運行的很好:))。但是我中途得到了下面的信息:

  1. i=5642j=c7 

等到運行完結束,末尾獲得了更多的記錄(整理crc文件匹配了我們損壞的文件)。有一個很好的機會,在中間的記錄,就是源代碼的問題

在一個十六進制編輯器中對字節稍微做了一些調整,zlib解壓縮(毫無錯誤!),然后管道輸出”git hash-object”,報告了損壞文件的shal值,成功了!

我修正packfile文件本身:

  1. chmod +w $pack 
  2. printf '\xc7' | dd of=$pack bs=1 seek=51659518 conv=notrunc 
  3. chmod -w $pack 

發現’\xc7′來自與替換我們的“munge”程序。把原來的對象偏移(51653873)導出了偏移量51659518 。通過“munge”(5642)增加了代替部分的偏移量,然后增加了之前去掉的3字節的git信息頭。

最后,”git fsck” 清理干凈。

關于沖突本身來說,我很幸運它確實是一個字節。實際上,證明就是單獨的位。0xc7字節發生沖突成為0xc5.所以推測由錯誤的硬件引起,或者物理射線。

緊接著,中止關注于解壓縮的輸出是錯的嗎?我本會一直看前面的部分這樣永遠不會發現它。下面是解壓縮后沖突數據的不同,真正的數據文件:

  1. -       cp = strtok (arg, "+"); 
  2. +       cp = strtok (arg, "."); 

調整了一個字節,最終仍然是有效的,可讀的C碰巧做了完全不同的事情!一次不同嘗試會造成幸運的日子,看看zlib的輸出可能確實有用,正如大多數隨機的改變也許就會破壞C代碼。

但更重要的是,git的hash、檢驗和引起了在另外一個系統中,很容易不被檢測問題。這個結果仍然會編譯,但是可能就引起一個有趣的bug(歸咎于一些隨機性的提交)

原文鏈接:http://thread.gmane.org/gmane.comp.version-control.git/236238

譯文鏈接:http://blog.jobbole.com/50108/

責任編輯:陳四芳 來源: 伯樂在線
相關推薦

2014-06-04 09:21:07

Swift開發語言

2011-08-29 16:41:14

OracleRMAN恢復數據文件的恢復

2012-06-13 01:23:30

開發者程序員

2024-03-07 08:55:24

JavaPython

2011-03-22 16:20:19

恢復數據庫

2010-02-03 09:06:26

Java EE 6

2015-09-08 09:55:28

手游設計資源

2023-07-07 08:15:18

JavaPython編寫

2009-06-30 10:40:28

Linux

2011-11-28 13:33:41

iOS

2014-06-04 11:25:39

Swift蘋果iOS

2009-07-02 19:07:25

Linux

2020-12-02 10:02:01

MacLinux蘋果

2013-08-07 10:04:37

MySQL數據恢復

2011-05-17 11:33:43

oracle數據庫

2017-04-01 18:00:08

開發者數據庫

2013-11-07 11:23:13

2010-05-06 09:42:28

Oracle表空間

2020-11-18 14:24:38

GitHubyoutube-dl庫開源

2023-11-08 18:01:53

硬重置Git命令
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成年视频在线观看福利资源 | 91在线视频一区 | 久久免费视频在线 | 成人在线中文字幕 | 国产一区在线免费观看 | 香蕉国产在线视频 | 自拍第一页 | 成人在线免费观看av | 欧美一区二区三区在线看 | 国产精品3区 | 国产精品久久久久久久7电影 | 久久久久国产一区二区三区 | 久久精品亚洲精品国产欧美 | 日韩一区中文字幕 | 中文字幕一区在线观看视频 | 国产精品国产a级 | 亚洲国产成人精 | 91一区二区 | 免费爱爱视频 | 日韩成人在线视频 | 免费看a | 久久久久久免费看 | 精品一区二区三区四区外站 | 国产精品久久久久久婷婷天堂 | 国产精品国产成人国产三级 | 欧美日韩精品久久久免费观看 | 免费一区在线 | 91精品一区| 毛片一区 | 日韩免费网| 成人一区精品 | 日本免费一区二区三区视频 | 色伊人久久 | www.一区二区 | 国产精品久久久久久久久久软件 | 国产精品免费观看 | 国产精品一级在线观看 | 亚洲精品久久久久久久久久久久久 | 狠狠久| 亚洲一区二区三区免费在线观看 | 国产高清一区二区三区 |