ubuntu 14.04でリリースアップデートを実行できません


27

現在、ubuntu 14.04ボックスをxenialにアップグレードしようとしています。私はリリースアップデートをしようとしていますが、UnicodeDecodeErrorのようなエラーで失敗します: 'utf-8'コーデックは位置382のバイト0x96をデコードできません:無効な開始バイト

それは既知のバグのように見えます-私はそれを試しましたが、問題のあるパッケージを見つけることができず、nodesourceおよびveeamリポジトリ用の2つの非標準package.lstファイルを無効化/削除しました。

トレースバックはこのようなものを読み取ります

Traceback (most recent call last):
  File "/tmp/ubuntu-release-upgrader-woadaq_z/xenial", line 8, in <module>
    sys.exit(main())
  File "/tmp/ubuntu-release-upgrader-woadaq_z/DistUpgrade/DistUpgradeMain.py", line 242, in main
    if app.run():
  File "/tmp/ubuntu-release-upgrader-woadaq_z/DistUpgrade/DistUpgradeController.py", line 1876, in run
    return self.fullUpgrade()
  File "/tmp/ubuntu-release-upgrader-woadaq_z/DistUpgrade/DistUpgradeController.py", line 1757, in fullUpgrade
    if not self.doPostInitialUpdate():
  File "/tmp/ubuntu-release-upgrader-woadaq_z/DistUpgrade/DistUpgradeController.py", line 943, in doPostInitialUpdate
    self.tasks = self.cache.installedTasks
  File "/tmp/ubuntu-release-upgrader-woadaq_z/DistUpgrade/DistUpgradeCache.py", line 806, in installedTasks
    for line in pkg._pcache._records.record.split("\n"):
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x96 in position 382: invalid start byte
Error in sys.excepthook:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/problem_report.py", line 416, in add_to_existing
    self.write(f)
  File "/usr/lib/python3/dist-packages/problem_report.py", line 369, in write
    block = f.read(1048576)
  File "/usr/lib/python3.4/codecs.py", line 319, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte

Original exception was:
Traceback (most recent call last):
  File "/tmp/ubuntu-release-upgrader-woadaq_z/xenial", line 8, in <module>
    sys.exit(main())
  File "/tmp/ubuntu-release-upgrader-woadaq_z/DistUpgrade/DistUpgradeMain.py", line 242, in main
    if app.run():
  File "/tmp/ubuntu-release-upgrader-woadaq_z/DistUpgrade/DistUpgradeController.py", line 1876, in run
    return self.fullUpgrade()
  File "/tmp/ubuntu-release-upgrader-woadaq_z/DistUpgrade/DistUpgradeController.py", line 1757, in fullUpgrade
    if not self.doPostInitialUpdate():
  File "/tmp/ubuntu-release-upgrader-woadaq_z/DistUpgrade/DistUpgradeController.py", line 943, in doPostInitialUpdate
    self.tasks = self.cache.installedTasks
  File "/tmp/ubuntu-release-upgrader-woadaq_z/DistUpgrade/DistUpgradeCache.py", line 806, in installedTasks
    for line in pkg._pcache._records.record.split("\n"):
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x96 in position 382: invalid start byte
=== Command terminated with exit status 1 (Mon Apr  3 09:31:21 2017) ===

そして、ログには本当に役立つものは何もありません。どうやってリリースリリースアップデートを機能させることができますか?

回答:


44

あなたが持っているのは、どこかで無効なデータをつまずくアップグレードスクリプト自体です。無効なデータを見つけて削除する必要があります。

この場合、パッケージveeamsnapでした。そのパッケージを削除すると修正されます。しかし、これはケースごとに異なるため、その結論に達するためにとった手順を説明します。それはかなり複雑なプロセスです。

python3文字列すべてUTF-8である必要があるため、これは楽しいものです。ここにあるのは(実際に発見された)Cモジュール(apt_pkg)で、何らかの理由で非UTF-8データをpython3文字列に挿入するため、文字列を読み取ろうとするたびにエラーが発生します。

未知の デバッガで行きます!

このような問題を診断する最善の方法は、失敗する行の前にデバッガーを一時停止させることです。Pythonでは、このような一連のネストされた呼び出しがある場合、デバッガーの一時停止を追加する最も簡単な方法は、ファイル自体を編集することです。

  1. あなたの例を使用すると、問題の失敗がファイル/tmp/ubuntu-release-upgrader-woadaq_z/DistUpgrade/DistUpgradeCache.py行806にあることがわかります。テキストエディタを起動して、その行に移動しましょう。一時パスは実行ごとに異なるため、エラー出力からのものを使用してください!

    エディターのスクリーンショット

  2. ここから、エラーの直前に行806に挿入することで、最初にデバッガーに簡単な一時停止を追加できimport pdb; pdb.set_trace();ます。これはPythonなので、インデントが重要です!

    デバッグ文のスクリーンショット

  3. 次に、変更したプログラムを実行する必要があります。do-release-upgrade再度実行しないでください。それはおそらく新しいものをダウンロードします。エラーログで、「元の例外があった」後の最初の行を参照してください。と1 /tmp/ubuntu-release-upgrader-woadaq_z/xenial?それがあなたが実行したいものです。そのため、そのファイルをルート(またはsudo)として実行します。

    これを実行すると、デバッガー(pdb)が表示されます。

    デバッガーのスクリーンショット

  4. ここから、合計でいくつのパッケージがあるかがわかります。それを行う簡単な方法は、実行することsum(1 for _ in self)です。少し待って(これにはしばらく時間がかかります)、数値が出力されます。この場合、それはでした76028

    現在、最初の数件ではおそらくエラーが発生しないため、75000を超えるパッケージを手動でステップ実行したくないため、例外ハンドラーを追加できません(エラーがひどいため、Python自体が破損するため) 、代替手段が必要です。

  5. 手順4で追加された行を削除します。コードを編集して、すべてのパッケージの増分番号を出力します。たとえば、foo = 0行802およびfoo += 1; print(foo)行807(エラー行の直前)のループの上に追加します。

    番号印刷コードのスクリーンショット

  6. 手順3と同じコマンドを使用して、コードを再度実行します。多数の数字のリストが出力されます。エラーが再び出力されるまで実行し続けます。ウィンドウを拡大する必要がある場合があります。

    数値出力のスクリーンショット

    その最後の番号は、クラッシュしたパッケージでなければなりません。その番号をメモしておきます。

  7. どのパッケージ/番号がクラッシュの原因であるかがわかったので、そのパッケージでのみ実行する条件でデバッガーの一時停止を追加します。たとえば、package 72285でクラッシュした場合if foo == 72285: import pdb; pdb.set_trace()、印刷する行の直後に追加しますfoo

    新しいpdbポーズのスクリーンショット

  8. コードを再度実行します。今、あなたがpdbそれに入ると、クラッシュを引き起こすパッケージ上にあるはずです。変数の名前を入力してpkgその値を出力することができ、現在のパッケージの名前がわかります:

    パッケージ名のスクリーンショット

    より一般的には、変数の名前を入力すると、その出力が出力されます。

  9. 問題のあるパッケージを削除し、アップグレードを再試行します(クリーンなdo-release-upgradeから)。


7
これは非常に素晴らしく、非常に穏やかなgdbの紹介であり、ほぼすべてのユーザーがさまざまなレベルの習熟度で使用できます。私からの+1、および称賛。ところで、デバッガでpkgと入力すると、803行目に定義されている同じ名前の変数の値が出力されることを追加できます。つまり、pkgはデバッガの命令ではありません。乾杯。
MariusMatutiae

@MariusMatutiae編集済み。そして、それはpdbです;)(これは実際には、この種の問題を解決することを目的としていますが、一般的なイントロとして簡単に理解できると便利です。)
ボブ

特にこの問題を解決するには、存在しないパッケージレコードに対してデバッグメッセージが出力するものをすべて出力するスクリプトに行を追加する方が簡単ではないでしょうか?(そのlogging.debugメッセージがすぐ上にあります)またはこれは、バグのためにpkg変数がまったく印刷できない可能性があり、pythonデバッガーは何でも印刷できると仮定していますか?
CausingUnderflowsEverywhere

スーパーユーザーブログがまだある場合、これは素晴らしい追加です。
カナダのルーク州立モニカ

@CausingUnderflowsEverywhere理論的には、はい。実際には、リンクされたバグレポートからの同様の提案は明らかに機能しませんでした(なぜ、OPが私に言ったことからわかりません)、そして何か他のものがクラッシュを引き起こした場合にインタラクティブにそれをしました-例えばこの場合、record読み取ることができなかったのはプロパティそのものだったことを知っておいてください。
ボブ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.