Không thể thực hiện cập nhật phát hành trên Ubuntu 14.04


27

Tôi hiện đang cố gắng nâng cấp hộp Ubuntu 14.04 lên xenial. Tôi đang cố gắng thực hiện cập nhật phát hành và nó không thành công với các lỗi như UnicodeDecodeError: 'utf-8' codec không thể giải mã byte 0x96 ở vị trí 382: byte bắt đầu không hợp lệ

Nó trông giống như một lỗi đã biết - Tôi đã thử nó và không may mắn tìm thấy gói vi phạm và đã vô hiệu hóa / xóa 2 tệp pack.lst không chuẩn của tôi cho các kho lưu trữ của nguồn và nút.

Trac trở lại đọc một cái gì đó như thế này

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

Và không có gì thực sự hữu ích trong nhật ký. Làm thế nào tôi có thể cập nhật do-phát hành để làm việc?

Câu trả lời:


44

Những gì bạn có là kịch bản nâng cấp tự vấp phải dữ liệu không hợp lệ ở đâu đó. Bạn cần tìm và xóa dữ liệu không hợp lệ.

Trong trường hợp này, nó là gói veeamsnap. Loại bỏ gói đó nên sửa nó. Nhưng vì điều này là khác nhau cho từng trường hợp, tôi sẽ mô tả các bước được thực hiện để đi đến kết luận đó. Đó là một quá trình khá phức tạp.

Đây là một niềm vui, bởi vì chuỗi python3 nên tất cả có trong UTF-8. Những gì bạn có ở đây (được phát hiện sau thực tế) là một mô-đun C ( apt_pkg) bằng cách nào đó chèn dữ liệu không phải UTF-8 vào chuỗi python3, do đó phá vỡ mọi nỗ lực đọc chuỗi - chú ý cách trình xử lý lỗi cũng ném ngoại lệ?

Into the biết debugger chúng tôi đi!

Cách tốt nhất để chẩn đoán các vấn đề như thế này là khiến trình gỡ lỗi tạm dừng trước khi dòng bị lỗi. Với Python, khi bạn có một loạt các cuộc gọi lồng nhau như thế này, cách dễ nhất để thêm tạm dừng trình gỡ lỗi là chỉnh sửa tệp.

  1. Sử dụng ví dụ của bạn, chúng ta có thể thấy rằng lỗi trong câu hỏi nằm ở /tmp/ubuntu-release-upgrader-woadaq_z/DistUpgrade/DistUpgradeCache.pydòng tệp 806, vì vậy hãy kích hoạt trình soạn thảo văn bản và chuyển đến dòng đó. Đường dẫn tạm thời sẽ khác nhau cho mỗi lần chạy, vì vậy hãy đảm bảo bạn sử dụng đường dẫn từ đầu ra lỗi của mình!

    ảnh chụp màn hình của biên tập viên

  2. Từ đây, trước tiên chúng ta có thể thêm một khoảng dừng đơn giản trong trình gỡ lỗi , bằng cách chèn import pdb; pdb.set_trace();vào dòng 806 ngay trước lỗi. Bởi vì đây là Python, việc thụt lề rất quan trọng!

    ảnh chụp màn hình của tuyên bố gỡ lỗi

  3. Bây giờ chúng ta cần chạy chương trình sửa đổi. Đừng chạy do-release-upgradelại; có thể sẽ tải xuống một cái mới. Xem trong nhật ký lỗi, dòng đầu tiên sau "Ngoại lệ ban đầu là"? Một với /tmp/ubuntu-release-upgrader-woadaq_z/xenial? Đó là thứ bạn muốn chạy. Vì vậy, chạy tập tin đó, như root (hoặc sudo).

    Chạy nó sẽ đưa bạn vào trình gỡ lỗi (pdb):

    ảnh chụp màn hình của trình gỡ lỗi

  4. Từ đây, chúng tôi tính ra có bao nhiêu gói có tổng cộng. Cách dễ dàng để làm điều đó là chạy sum(1 for _ in self). Đợi một chút (điều này có thể mất một lúc) và nó sẽ in một số. Trong trường hợp này, nó đã được 76028.

    Bây giờ, vì lỗi có thể không xảy ra trong một vài lần đầu tiên và chúng tôi không muốn tự mình bước qua> 75000 gói và chúng tôi không thể thêm một trình xử lý ngoại lệ (vì lỗi rất tệ nên nó tự phá vỡ Python) , chúng ta cần một sự thay thế.

  5. Xóa dòng được thêm vào trong bước 4. Chỉnh sửa mã để in số tăng dần cho mỗi gói. Ví dụ: thêm foo = 0phía trên vòng lặp trên dòng 802 và foo += 1; print(foo)trên dòng 807 (ngay trước dòng lỗi).

    ảnh chụp màn hình mã in số

  6. Chạy lại mã, sử dụng lệnh tương tự như trong bước 3. Nó sẽ in một danh sách lớn các số. Hãy để nó tiếp tục chạy cho đến khi nó in lại lỗi. Bạn có thể cần phải phóng to cửa sổ của mình:

    ảnh chụp màn hình đầu ra số

    Số cuối cùng sẽ là gói nó bị rơi. Hãy ghi chú số đó.

  7. Bây giờ bạn đã biết gói / số nào gây ra sự cố, đã đến lúc thêm trình tạm dừng trình gỡ lỗi với một điều kiện để chỉ thực hiện trên gói đó. Ví dụ: nếu bạn gặp sự cố trên gói 72285, hãy thêm if foo == 72285: import pdb; pdb.set_trace()ngay sau dòng in foo:

    ảnh chụp màn hình tạm dừng pdb mới

  8. Chạy lại mã. Bây giờ khi bạn nhận được vào pdbnó nên nằm trên gói gây ra sự cố. Bạn có thể nhập tên của biến pkgđể in giá trị của nó, nó sẽ cho bạn biết tên của gói hiện tại:

    ảnh chụp màn hình tên gói

    Tổng quát hơn, gõ tên của bất kỳ biến nào sẽ in đầu ra của nó.

  9. Xóa gói vi phạm và thử nâng cấp lại (từ bản nâng cấp do phát hành sạch).


7
Đây là một đoạn giới thiệu rất hay, rất nhẹ nhàng với gdb, có thể được sử dụng với các mức độ thành thạo khác nhau chỉ bằng bất kỳ người dùng nào. +1 từ tôi và danh tiếng. Và, BTW, bạn chỉ có thể thêm rằng gõ pkg trong trình gỡ lỗi sẽ in giá trị của biến cùng tên, như được định nghĩa trên dòng 803. Nói cách khác, pkg không phải là hướng dẫn của trình gỡ lỗi. Chúc mừng.
MariusMatutiae

@MariusMatutiae Đã chỉnh sửa. Và đó là pdb;) (Điều này thực sự được dự định cụ thể hơn để giải quyết loại vấn đề này, nhưng thật tuyệt khi bạn thấy dễ dàng theo dõi như một phần giới thiệu chung.)
Bob

Để giải quyết vấn đề này một cách cụ thể, sẽ dễ dàng hơn nếu chỉ thêm một dòng vào tập lệnh in bất cứ thứ gì mà thông báo gỡ lỗi muốn in cho bản ghi gói không tồn tại? .
CausingUnderflowsEverywhere

Nếu chúng ta vẫn có blog Siêu người dùng, đây sẽ là một bổ sung tuyệt vời cho nó!
Luke Luke REINSTATE MONICA của Canada

@CausingUnderflowsEverywhere Về lý thuyết, vâng. Trong thực tế, một đề xuất tương tự từ báo cáo lỗi được liên kết dường như không hoạt động (tôi không chắc tại sao, chỉ từ những gì OP nói với tôi) và cuối cùng tôi đã thực hiện nó một cách tương tác trong trường hợp có thứ gì đó gây ra sự cố - ví dụ như không biết rằng trong trường hợp này, đó là recordtài sản không thể đọc được.
Bob
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.