Ubuntu 14.04’te yayın güncellemesi yapılamıyor


27

Şu anda ubuntu 14.04 kutusunu xenial sürümüne yükseltmeye çalışıyorum. Sürüm güncellemesi yapmaya çalışıyorum ve UnicodeDecodeError: 'utf-8' codec'i gibi hatalarla başarısız oluyor ve 382 no'lu konumdaki 0x96 baytının kodunu çözemiyor: geçersiz başlangıç ​​baytı

Bilinen bir hataya benziyor - bunu denedim ve rahatsız edici paketi bulma şansım olmadı ve standart olmayan 2 paketim.lst dosyalarını düğüm ve veeam depoları için devre dışı bıraktım / kaldırdım.

Traceback böyle bir şey okuyor

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) ===

Ve kayıtlarda gerçekten yardımcı olacak hiçbir şey yok. Yayın güncellemesini nasıl çalıştırabilirim?

Yanıtlar:


44

Elinizde olan şey, yükseltme betiğinin bir yerdeki geçersiz veriler üzerinden geçmesidir. Geçersiz verileri bulmanız ve kaldırmanız gerekir.

Bu durumda, paket oldu veeamsnap. Bu paketi çıkarmak onu düzeltmeli. Ancak bu her durum için farklı olduğu için, bu sonuca ulaşmak için attığım adımları açıklayacağım. Bu oldukça karmaşık bir süreçtir.

Bu eğlenceli bir şey, çünkü python3 dizelerinin hepsinin UTF-8'de olması gerekir . Burada sahip olduğun şey (gerçeklerden sonra keşfedilen) bir C modülüdür ( apt_pkg) bir şekilde UTF-8 verilerini python3 dizgisine ekliyor, bu nedenle dizgiyi okumadaki her girişimi engelliyor - hata işleyicisinin kendisinin de bir istisna attığını fark ettiniz mi?

İçine bilinmeyen ayıklayıcıya gidiyoruz!

Bu gibi sorunları teşhis etmenin en iyi yolu, hata ayıklayıcının başarısız olan satırdan önce duraklamasına neden olmaktır. Python ile, bir hata ayıklama duraklatması eklemenin en kolay yolu, bunun gibi iç içe geçmiş bir çağrınız olduğunda, dosyanın kendisini düzenlemektir.

  1. Örneğinizi kullanarak, söz konusu hatanın /tmp/ubuntu-release-upgrader-woadaq_z/DistUpgrade/DistUpgradeCache.py806 dosya satırında olduğunu görebiliriz , o yüzden bir metin düzenleyiciyi ateşleyelim ve o satıra gidelim. Temp yolu her çalışma için farklı olacaktır, bu yüzden onu hata çıktınızdan kullandığınızdan emin olun!

    editörün ekran görüntüsü

  2. Buradan , hatadan hemen önce 806 satırını ekleyerek hata ayıklayıcısına basit bir duraklama ekleyebilirizimport pdb; pdb.set_trace(); . Bu Python olduğundan çentiklenme önemlidir!

    hata ayıklama ifadesinin ekran görüntüsü

  3. Şimdi değiştirilmiş programı çalıştırmamız gerekiyor. do-release-upgradeTekrar koşma ; Bu muhtemelen yeni bir tane indirir. Hata günlüklerine bakın, "Orijinal istisna" ndan sonraki ilk satır? Beraber /tmp/ubuntu-release-upgrader-woadaq_z/xenialmi? Koşmak istediğin bu. Öyleyse bu dosyayı root (veya sudo) olarak çalıştırın.

    Koşmak sizi hata ayıklayıcısına (pdb) götürecek:

    hata ayıklayıcısının ekran görüntüsü

  4. Buradan toplamda kaç tane paket olduğunu bulduk. Bunu yapmanın kolay yolu kaçmaktır sum(1 for _ in self). Biraz bekleyin (bu biraz zaman alabilir) ve bir sayı basacaktır. Bu durumda öyleydi 76028.

    Şimdi, hata muhtemelen ilk birkaçta meydana gelmediğinden ve> 75000 paketlerini elle adım adım atmak istemiyoruz ve bir istisna eylemcisi ekleyemiyoruz (hata çok kötü olduğu için Python'u kırar) alternatifine ihtiyacımız var.

  5. 4. adımda eklenen çizgiyi kaldırın. Her pakete artan bir sayı yazdırmak için kodu düzenleyin. Örneğin, foo = 0802 satırındaki ve foo += 1; print(foo)807 satırındaki döngünün üstüne ekleyin (hata satırından hemen önce).

    sayı yazdırma kodunun ekran görüntüsü

  6. Kodu, 3. adımdakiyle aynı komutu kullanarak tekrar çalıştırın. Çok sayıda numara yazdırır. Hatayı tekrar yazana kadar çalışmaya devam etmesine izin verin. Pencerenizi büyütmeniz gerekebilir:

    sayı çıktısının ekran görüntüsü

    Bu son numara, çarptığı paket olmalıdır. Bu numarayı not edin.

  7. Artık hangi paketin / sayının çökmeye neden olduğunu bildiğinize göre, hata ayıklayıcı duraklatmasını yalnızca bu pakette çalıştırma koşulu ile ekleme zamanı gelmiştir. Örneğin, pakette kilitlenirseniz, yazdırılan satırın hemen arkasına 72285ekleyin :if foo == 72285: import pdb; pdb.set_trace()foo

    yeni pdb duraklatmasının ekran görüntüsü

  8. Kodu tekrar çalıştır. Şimdi girdiğiniz zaman pdbçökmeye neden olan pakette olmalı. pkgDeğerini yazdırmak için değişkenin adını yazabilirsiniz , bu da size mevcut paketin adını söyler:

    paket adının ekran görüntüsü

    Daha genel olarak, herhangi bir değişkenin adına yazmak, çıktısını basacaktır.

  9. Sorunlu paketi çıkarın ve yükseltmeyi tekrar deneyin (temiz sürüm yükseltme yükseltmesinden).


7
Bu, hemen hemen her kullanıcı tarafından farklı yeterlilik seviyelerinde kullanılabilen gdb'ye çok hoş, çok yumuşak bir introdur. + 1 benden ve kudos. Ve BTW, hata ayıklayıcısına pkg yazmanın , aynı addaki değişkenin değerini, 803 satırında tanımlandığı gibi yazdıracağını ekleyebilirsiniz . Başka bir deyişle, pkg bir hata ayıklama talimatı değildir. Şerefe.
MariusMatutiae

@MariusMatutiae Düzenlendi. Ve pdb;) (Bu, aslında bu problem sınıfını çözme konusunda daha spesifik olması gerekiyordu, ancak genel bir giriş olarak takip etmeyi kolay bulmanız çok güzel.)
Bob

Özellikle bu sorunu çözmek için, bu hata ayıklama iletisinin varolmayan bir paket kaydı için yazdırmak istediği her şeyi basan betiğe bir satır eklemek daha kolay olmaz mıydı? (Aşağıdaki logging.debug mesajının hemen üstünde) Veya bu, pkg değişkeninin hata nedeniyle hiç yazdırılamayacağını varsayar ve python hata ayıklayıcısı herhangi bir şeyi yazdırabilir mi?
Nedeni ToplayanlarHer yerde

Hala Süper Kullanıcı bloğumuz varsa, bu mükemmel bir eklenti olur!
Kanadalı Luke MONICA'YI

@Hareketli İfadeleri Her Yerde Teoride, evet. Uygulamada, bağlantılı hata raporundan benzer bir öneri görünüşte işe yaramadı (neden OP'nin bana söylediğinden tam olarak emin değilim) ve başka bir kazayı tetiklemesi durumunda etkileşimli olarak yaptım - örn. Bu durumda, recordokunamayan mülkün kendisi olduğunu biliyoruz .
Bob
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.