Cuộc săn bọ khó khăn nhất của bạn là gì và làm thế nào bạn tìm thấy nó và tiêu diệt nó?


31

Đây là một câu hỏi "Chia sẻ kiến ​​thức". Tôi quan tâm đến việc học hỏi từ những thành công và / hoặc thất bại của bạn.

Thông tin có thể hữu ích ...

Lý lịch:

  • Bối cảnh: Ngôn ngữ, Ứng dụng, Môi trường, v.v.
  • Làm thế nào là lỗi được xác định?
  • Ai hoặc cái gì xác định lỗi?
  • Làm thế nào phức tạp đã tái tạo lỗi?

Cuộc săn lùng.

  • Kế hoạch của bạn là gì?
  • Những khó khăn bạn đã gặp phải?
  • Mã vi phạm cuối cùng đã được tìm thấy như thế nào?

Việc giết chóc.

  • Làm thế nào phức tạp là sửa chữa?
  • Làm thế nào bạn xác định phạm vi của sửa chữa?
  • Có bao nhiêu mã đã tham gia vào việc sửa chữa?

Hậu họa.

  • Nguyên nhân gốc rễ là gì? tràn bộ đệm, vv
  • Nguyên nhân gốc rễ từ 30.000 ft là gì?
  • Quá trình cuối cùng mất bao lâu?
  • Có bất kỳ tính năng nào bị ảnh hưởng xấu bởi bản sửa lỗi không?
  • Những phương pháp, công cụ, động lực nào bạn thấy đặc biệt hữu ích? ... Vô dụng khủng khiếp?
  • Nếu bạn có thể làm lại tất cả? ............

Những ví dụ này là chung chung, không áp dụng trong mọi tình huống và có thể vô dụng. Hãy mùa khi cần thiết.

Câu trả lời:


71

Nó thực sự nằm trong thành phần phụ của trình xem ảnh bên thứ 3 trong ứng dụng của chúng tôi.

Chúng tôi thấy rằng có 2-3 người dùng ứng dụng của chúng tôi sẽ thường xuyên có thành phần trình xem ảnh ném ngoại lệ và chết một cách khủng khiếp. Tuy nhiên, chúng tôi đã có hàng tá người dùng khác chưa bao giờ thấy vấn đề mặc dù sử dụng ứng dụng cho cùng một nhiệm vụ trong hầu hết các ngày làm việc. Ngoài ra, có một người dùng đặc biệt nhận được nó thường xuyên hơn những người còn lại.

Chúng tôi đã thử các bước thông thường:

(1) Họ đã chuyển đổi máy tính với một người dùng khác chưa bao giờ gặp sự cố để loại trừ máy tính / cấu hình. - Vấn đề theo họ.

(2) Có họ đăng nhập vào ứng dụng và làm việc như một người dùng không bao giờ thấy vấn đề. - Vấn đề VẪN theo họ.

(3) Yêu cầu người dùng báo cáo hình ảnh họ đang xem và thiết lập khai thác thử nghiệm để lặp lại xem hình ảnh đó hàng nghìn lần liên tiếp. Vấn đề không xuất hiện trong khai thác.

(4) Có một nhà phát triển ngồi với người dùng và xem họ cả ngày. Họ đã nhìn thấy các lỗi, nhưng không nhận thấy họ làm bất cứ điều gì khác thường để gây ra chúng.

Chúng tôi đã vật lộn với điều này trong nhiều tuần để cố gắng tìm ra "Người dùng lỗi" có điểm gì chung mà những người dùng khác không làm được. Tôi không biết làm thế nào, nhưng nhà phát triển ở bước (4) đã có một khoảnh khắc eureka trên đường lái xe đi làm một ngày xứng đáng với Encyclopedia Brown.

Anh nhận ra rằng tất cả "Người dùng lỗi" đều thuận tay trái và đã xác nhận sự thật này. Chỉ người dùng thuận tay trái mới mắc lỗi, không bao giờ Righties. Nhưng làm thế nào có thể thuận tay trái gây ra một lỗi?

Chúng tôi đã cho anh ấy ngồi xuống và xem những người thuận tay trái một lần nữa đặc biệt chú ý đến bất cứ điều gì họ có thể làm khác đi, và đó là cách chúng tôi tìm thấy nó.

Hóa ra lỗi chỉ xảy ra nếu bạn di chuyển chuột đến cột pixel ngoài cùng bên phải trong trình xem ảnh trong khi nó đang tải một hình ảnh mới (lỗi tràn vì nhà cung cấp đã tính toán 1 lần cho sự kiện di chuột qua).

Rõ ràng, trong khi chờ đợi hình ảnh tiếp theo được tải, tất cả người dùng đều tự nhiên di chuyển bàn tay của họ (và do đó là chuột) về phía bàn phím.

Người dùng thường xuyên gặp phải lỗi này là một trong những loại ADD bắt buộc di chuyển con chuột của mình xung quanh rất nhiều trong khi chờ tải trang tiếp theo, do đó cô ấy di chuyển chuột sang bên phải nhanh hơn rất nhiều và nhấn đúng thời điểm để cô ấy làm điều đó khi sự kiện tải xảy ra. Cho đến khi chúng tôi nhận được một bản sửa lỗi từ nhà cung cấp, chúng tôi đã nói với cô ấy chỉ cần thả chuột sau khi nhấp (tài liệu tiếp theo) và không chạm vào nó cho đến khi nó được tải.

Từ đó được biết đến trong truyền thuyết về đội nhà phát triển là "Con bọ tay trái"


14
Đó là điều xấu nhất tôi từng nghe nói.
Nathan Taylor

9
Mặc dù vậy, nó đã tạo ra một anh hùng từ người đã giải quyết nó.
JohnFx

2
Wow, bây giờ là một lỗi của một lỗi!
Người bán Mitchel

3
Tuyệt vời tìm thấy! Câu truyện hay.
Toon Krijthe

11
Như thể những người cánh tả của chúng ta chưa được đối xử đủ như những công dân hạng hai. Bây giờ chúng tôi cũng phải chịu nhiều phiền toái hơn so với phần lỗi công bằng của chúng tôi ... gee, cảm ơn! : p
Dan Mould

11

Đây là từ một thời gian dài trước đây (cuối những năm 1980).

Công ty tôi làm việc đã viết một gói CAD (bằng FORTRAN) chạy trên các máy trạm Unix khác nhau (HP, Sun, Silcon Graphics, v.v.). Chúng tôi đã sử dụng định dạng tệp của riêng mình để lưu trữ dữ liệu và khi gói bắt đầu không gian đĩa khan hiếm nên có rất nhiều dịch chuyển bit được sử dụng để lưu trữ nhiều cờ trong các tiêu đề thực thể.

Loại thực thể (dòng, cung, văn bản, v.v.) được nhân với 4096 (tôi nghĩ) khi được lưu trữ. Ngoài ra, giá trị này đã bị phủ định để chỉ ra một mục đã bị xóa. Vì vậy, để có được loại chúng tôi đã có mã đã làm:

type = record[1] MOD 4096

Trên mỗi máy ngoại trừ một máy này đã cho ± 1 (cho một dòng), ± 2 (cho một cung), v.v. và sau đó chúng tôi có thể kiểm tra dấu hiệu để xem có bị xóa hay không.

Trên một máy (HP tôi nghĩ) chúng tôi đã gặp phải một vấn đề kỳ lạ khi việc xử lý các mục bị xóa bị vặn.

Đó là vào thời trước khi các trình gỡ lỗi trực quan và IDE nên tôi phải chèn các câu lệnh theo dõi và ghi nhật ký để thử và theo dõi vấn đề.

Cuối cùng tôi đã phát hiện ra rằng đó là vì trong khi mọi nhà sản xuất khác thực hiện MODthì -4096 MOD 4096kết quả là -1HP đã triển khai nó một cách chính xác về mặt toán học để -4096 MOD 4096kết quả là -4097.

Cuối cùng tôi đã phải đi qua toàn bộ cơ sở mã lưu dấu của giá trị và làm cho nó dương trước khi thực hiện MODvà sau đó nhân kết quả với giá trị dấu.

Điều này mất vài ngày.


3
Có lẽ đã có nhiều cuộc săn lỗi khó khăn hơn trong những năm qua, nhưng điều này đã bị mắc kẹt trong tâm trí tôi trong hơn 20 năm!
ChrisF

7

Wow, đọc tốt ở đây!

Khó khăn nhất của tôi là nhiều năm trở lại đây khi Turbo Pascal lớn, mặc dù nó có thể là một trong những IDE C ++ đầu tiên thời bấy giờ. Là nhà phát triển duy nhất (và là người thứ ba tại startup này), tôi đã viết một cái gì đó giống như một chương trình CAD thân thiện với nhân viên bán hàng. Nó là tuyệt vời vào thời điểm đó, nhưng đã phát triển một vụ tai nạn ngẫu nhiên khó chịu. Không thể sao chép, nhưng đã xảy ra thường xuyên đến mức tôi bắt đầu săn lùng lỗi.

Chiến lược tốt nhất của tôi là một bước trong trình gỡ lỗi. Lỗi chỉ xảy ra khi người dùng đã nhập đủ bản vẽ và có thể phải ở một chế độ hoặc trạng thái thu phóng nhất định, do đó, có rất nhiều cài đặt tẻ nhạt và xóa các điểm dừng, chạy bình thường trong một phút để vào bản vẽ, sau đó bước qua một đoạn mã lớn Đặc biệt hữu ích là các điểm dừng sẽ bỏ qua một số lần điều chỉnh sau đó phá vỡ. Toàn bộ bài tập này đã được lặp đi lặp lại nhiều lần.

Cuối cùng, tôi thu hẹp nó xuống một nơi mà một chương trình con đang được gọi, được cho 2 nhưng từ bên trong nó thấy một số vô nghĩa. Tôi có thể đã bắt được điều này sớm hơn, nhưng đã không bước vào chương trình con này, cho rằng nó đã nhận được những gì nó đã được đưa ra. Mù quáng bằng cách cho rằng những điều đơn giản nhất là ổn!

Hóa ra là nhồi int 16 bit trên ngăn xếp, nhưng chương trình con mong đợi 32 bit. Hoặc điều tương tự. Trình biên dịch không tự động đệm tất cả giá trị lên 32 bit hoặc kiểm tra kiểu đủ. Nó là tầm thường để sửa chữa, chỉ là một phần của một dòng, hầu như không cần suy nghĩ. Nhưng để đến đó phải mất ba ngày săn lùng và đặt câu hỏi rõ ràng.

Vì vậy, tôi có kinh nghiệm cá nhân với giai thoại đó về nhà tư vấn đắt giá xuất hiện, sau một thời gian thực hiện một cú nhấn ở đâu đó và tính phí 2000 đô la. Các giám đốc điều hành yêu cầu một sự cố, và đó là $ 1 cho vòi, $ 1999 để biết nơi để nhấn. Ngoại trừ trong trường hợp của tôi, đó là thời gian không phải là tiền.

Bài học rút ra: 1) sử dụng trình biên dịch tốt nhất, trong đó "tốt nhất" được định nghĩa là bao gồm kiểm tra xem có bao nhiêu vấn đề vì khoa học máy tính biết cách kiểm tra và 2) đặt câu hỏi về những điều hiển nhiên đơn giản hoặc ít nhất là xác minh chức năng phù hợp của chúng.

Kể từ đó, tất cả các lỗi khó đã thực sự khó khăn, vì tôi biết kiểm tra những điều đơn giản kỹ lưỡng hơn dường như là cần thiết.

Bài học 2 cũng áp dụng cho lỗi điện tử khó nhất mà tôi từng sửa, cũng với một sửa chữa tầm thường, nhưng một số EE thông minh đã bị vấp ngã trong nhiều tháng. Nhưng đây không phải là một diễn đàn điện tử, vì vậy tôi sẽ không nói thêm về điều đó.


Xin vui lòng gửi các lỗi điện tử ở nơi khác và một liên kết ở đây!
tgkprog

6

Điều kiện cuộc đua dữ liệu mạng từ địa ngục

Tôi đã viết một máy khách / máy chủ mạng (Windows XP / C #) để làm việc với một ứng dụng tương tự trên máy trạm thực sự cũ (Encore 32/77) được viết bởi một nhà phát triển khác.

Những gì ứng dụng đã làm về cơ bản là chia sẻ / thao tác dữ liệu nhất định trên máy chủ để kiểm soát quá trình máy chủ chạy hệ thống với giao diện người dùng màn hình cảm ứng đa màn hình dựa trên PC ưa thích của chúng tôi.

Nó đã làm điều này với cấu trúc 3 lớp. Quá trình truyền thông đọc / ghi dữ liệu đến / từ máy chủ, đã thực hiện tất cả các chuyển đổi định dạng cần thiết (endianness, định dạng dấu phẩy động, v.v.) và ghi / đọc các giá trị đến / từ cơ sở dữ liệu. Cơ sở dữ liệu hoạt động như một trung gian dữ liệu giữa các comms và UI màn hình cảm ứng. Ứng dụng của giao diện người dùng màn hình cảm ứng được tạo ra giao diện màn hình cảm ứng dựa trên số lượng màn hình được gắn vào PC (nó tự động phát hiện ra điều này).

Trong khung thời gian được cung cấp một gói giá trị giữa máy chủ và máy tính của chúng tôi chỉ có thể gửi tối đa 128 giá trị qua dây với thời gian trễ tối đa ~ 110ms mỗi chuyến khứ hồi (UDP được sử dụng với kết nối ethernet trực tiếp giữa các máy tính). Vì vậy, số lượng biến được phép dựa trên số lượng màn hình cảm ứng đính kèm được kiểm soát chặt chẽ. Ngoài ra, máy chủ (mặc dù có kiến ​​trúc đa bộ xử lý khá phức tạp với bus bộ nhớ dùng chung cho điện toán thời gian thực) có sức mạnh xử lý khoảng 1/100 của điện thoại di động của tôi nên nó được giao nhiệm vụ xử lý ít nhất có thể và đó là máy chủ / client phải được viết thành hội đồng để đảm bảo điều này (máy chủ đang chạy mô phỏng toàn thời gian thực mà không thể bị ảnh hưởng bởi chương trình của chúng tôi).

Vấn đề là. Một số giá trị, khi được thay đổi trên màn hình cảm ứng sẽ không chỉ lấy giá trị mới nhập mà sẽ xoay vòng ngẫu nhiên giữa giá trị đó và giá trị trước đó. Điều đó và chỉ trên một vài giá trị cụ thể trên một vài trang cụ thể với sự kết hợp các trang nhất định từng thể hiện triệu chứng. Chúng tôi gần như đã bỏ lỡ vấn đề hoàn toàn cho đến khi chúng tôi bắt đầu chạy nó thông qua quy trình chấp nhận khách hàng ban đầu


Để xác định vấn đề, tôi chọn một trong các giá trị dao động:

  • Tôi đã kiểm tra ứng dụng Màn hình cảm ứng, nó đang dao động
  • Tôi đã kiểm tra cơ sở dữ liệu, dao động
  • Tôi đã kiểm tra ứng dụng comms, dao động

Sau đó, tôi đã phá vỡ wireshark và bắt đầu giải mã thủ công các gói chụp. Kết quả:

  • Không dao động nhưng các gói trông không ổn, có quá nhiều dữ liệu.

Tôi đã xem qua từng chi tiết của mã comms hàng trăm lần mà không tìm thấy lỗi / lỗi nào.

Cuối cùng, tôi bắt đầu bắn email cho các nhà phát triển khác hỏi chi tiết cách kết thúc của anh ta để xem liệu tôi có thiếu thứ gì không. Sau đó, tôi tìm thấy nó.

Rõ ràng, khi anh ta gửi dữ liệu, anh ta đã không xóa mảng dữ liệu trước khi truyền, vì vậy, về cơ bản, anh ta chỉ ghi đè lên bộ đệm cuối cùng được sử dụng với các giá trị mới ghi đè lên giá trị cũ, nhưng các giá trị cũ không được ghi đè vẫn được truyền đi.

Vì vậy, nếu một giá trị ở vị trí 80 của mảng dữ liệu và danh sách các giá trị được yêu cầu thay đổi thành nhỏ hơn 80 nhưng cùng một giá trị được chứa trong danh sách mới, thì cả hai giá trị sẽ tồn tại trong bộ đệm dữ liệu cho bộ đệm cụ thể đó thời gian nhất định.

Giá trị được đọc từ cơ sở dữ liệu phụ thuộc vào lát thời gian khi UI yêu cầu giá trị.


Việc sửa chữa rất đơn giản. Đọc số lượng mục đến trên bộ đệm dữ liệu (Nó thực sự được chứa như một phần của giao thức gói) và không đọc bộ đệm vượt quá số lượng mục đó.


Bài học kinh nghiệm:

  • Đừng coi sức mạnh tính toán hiện đại là điều hiển nhiên. Đã có lúc máy tính không hỗ trợ ethernet và khi xả một mảng có thể được coi là đắt tiền. Nếu bạn thực sự muốn xem chúng ta đã đi được bao xa, hãy tưởng tượng một hệ thống hầu như không có hình thức cấp phát bộ nhớ động. IE, quy trình điều hành phải phân bổ trước tất cả bộ nhớ cho tất cả các chương trình theo thứ tự và không có chương trình nào có thể phát triển vượt ra ngoài ranh giới đó. IE, phân bổ thêm bộ nhớ cho một chương trình mà không biên dịch lại toàn bộ hệ thống có thể gây ra sự cố lớn. Tôi tự hỏi nếu mọi người sẽ nói về những ngày thu gom rác trong cùng một ngày nào đó.

  • Khi thực hiện kết nối mạng với các giao thức tùy chỉnh (hoặc xử lý biểu diễn dữ liệu nhị phân nói chung), hãy đảm bảo bạn đọc thông số kỹ thuật cho đến khi bạn hiểu mọi chức năng của mọi giá trị được gửi qua đường ống. Ý tôi là, đọc nó cho đến khi mắt bạn đau. Mọi người xử lý dữ liệu bằng cách thao tác các bit hoặc byte riêng lẻ có cách làm rất thông minh và hiệu quả. Thiếu chi tiết nhỏ nhất có thể phá vỡ hệ thống.

Tổng thời gian để khắc phục là 2-3 ngày với phần lớn thời gian dành cho việc khác khi tôi cảm thấy thất vọng với điều này.

SideNote: Theo mặc định, máy tính chủ không hỗ trợ ethernet. Thẻ để lái nó đã được tùy chỉnh và trang bị thêm và ngăn xếp giao thức hầu như không tồn tại. Nhà phát triển mà tôi đang làm việc là một lập trình viên, anh ta không chỉ triển khai một phiên bản rút gọn của UDP và một ngăn xếp ethernet giả bắt chước (bộ xử lý không đủ mạnh để xử lý một ngăn xếp ethernet đầy đủ) trên hệ thống cho dự án này nhưng anh ấy đã làm nó trong vòng chưa đầy một tuần. Ông cũng là một trong những người lãnh đạo nhóm dự án ban đầu, người đã thiết kế và lập trình HĐH ngay từ đầu. Hãy nói, bất cứ điều gì anh ấy từng chia sẻ về máy tính / lập trình / kiến ​​trúc cho dù tôi có mới bao lâu hay chưa, tôi đã lắng nghe từng từ.


5

Bối cảnh

  • Trong một nhiệm vụ quan trọng, ứng dụng WCF điều khiển một trang web và cung cấp xử lý giao dịch phụ trợ ..
  • Ứng dụng âm lượng lớn (hàng trăm cuộc gọi mỗi giây)
  • Nhiều máy chủ nhiều trường hợp
  • Hàng trăm bài kiểm tra đơn vị đã qua và vô số cuộc tấn công QA

Con bọ

  • Khi được chuyển sang sản xuất, máy chủ sẽ chạy tốt trong một khoảng thời gian ngẫu nhiên sau đó bắt đầu xuống cấp nhanh chóng và đưa CPU hộp lên 100%.

Làm thế nào tôi tìm thấy nó

Lúc đầu, tôi chắc chắn đây là một vấn đề hiệu suất bình thường vì vậy tôi tạo ra việc ghi nhật ký công phu. Kiểm tra hiệu suất trên mỗi cuộc gọi nói chuyện với cơ sở dữ liệu về việc sử dụng đã theo dõi các máy chủ về các vấn đề. 1 tuần

Sau đó, tôi chắc chắn rằng tôi có một vấn đề tranh chấp chủ đề. Tôi đã kiểm tra các bế tắc của mình đã cố gắng tạo ra các công cụ tạo tình huống để cố gắng tạo ra tình huống trong gỡ lỗi. Với sự thất vọng trong quản lý ngày càng tăng, tôi đã chuyển sang các đồng nghiệp của mình về cách đề xuất mọi thứ từ khởi động lại dự án từ đầu đến giới hạn máy chủ trong một luồng. 1,5 tuần

Rồi tôi nhìn Tess Ferrandez blog đã tạo ra một tệp kết xuất người dùng và chú thích nó với Windebug vào lần tiếp theo khi máy chủ lấy một bãi chứa. Tìm thấy rằng tất cả các chủ đề của tôi đã bị mắc kẹt trong chức năng dictionary.add.

Từ điển ngắn dài chỉ theo dõi nhật ký ghi lỗi x chủ đề không được đồng bộ hóa.


3

Chúng tôi đã có một ứng dụng đang nói chuyện với một thiết bị phần cứng, trong một số trường hợp, sẽ không hoạt động chính xác nếu thiết bị được rút phích cắm vật lý cho đến khi nó được cắm lại và thiết lập lại mềm hai lần.

Vấn đề hóa ra là một ứng dụng đang chạy khi khởi động thỉnh thoảng bị lỗi khi nó đang cố đọc từ một hệ thống tệp chưa được gắn (ví dụ: nếu người dùng định cấu hình để đọc từ ổ NFS). Khi khởi động, ứng dụng sẽ gửi một số ioctls cho trình điều khiển để khởi tạo thiết bị, sau đó đọc cài đặt cấu hình và gửi thêm ioctls để đặt thiết bị ở trạng thái chính xác.

Một lỗi trong trình điều khiển đã khiến giá trị không hợp lệ được ghi vào thiết bị khi cuộc gọi khởi tạo được thực hiện, nhưng giá trị được ghi đè bằng dữ liệu hợp lệ sau khi các cuộc gọi được thực hiện để đặt thiết bị ở trạng thái cụ thể.

Thiết bị này có pin và sẽ phát hiện nếu nó bị mất nguồn từ bo mạch chủ và sẽ viết một lá cờ vào bộ nhớ dễ bay hơi cho biết rằng nó bị mất điện, sau đó nó sẽ chuyển sang trạng thái cụ thể vào lần tiếp theo khi bật nguồn và cụ thể hướng dẫn cần thiết để được gửi để xóa cờ.

Vấn đề là nếu nguồn điện bị loại bỏ một khi ioctls đã được gửi để khởi tạo thiết bị (và ghi giá trị không hợp lệ vào thiết bị) nhưng trước khi dữ liệu hợp lệ có thể được gửi. Khi thiết bị được bật lại, nó sẽ thấy cờ đã được đặt và cố gắng đọc dữ liệu không hợp lệ được gửi từ trình điều khiển do quá trình kích hoạt không hoàn chỉnh. Điều này sẽ đặt thiết bị ở trạng thái không hợp lệ, nơi cờ tắt nguồn đã bị xóa nhưng thiết bị sẽ không nhận được hướng dẫn thêm cho đến khi trình điều khiển được khởi động lại. Thiết lập lại thứ hai có nghĩa là thiết bị đã không cố đọc dữ liệu không hợp lệ được lưu trữ trên đó và sẽ nhận được hướng dẫn cấu hình chính xác, cho phép thiết bị được đưa vào trạng thái chính xác (giả sử ứng dụng gửi ioctls không bị lỗi ).

Cuối cùng, mất khoảng hai tuần để tìm ra tập hợp chính xác các tình huống gây ra vấn đề.


2

Đối với một dự án Đại học, chúng tôi đã viết một hệ thống P2P phân tán chia sẻ các tệp, điều này được hỗ trợ đa tuyến để phát hiện lẫn nhau, nhiều vòng nút và máy chủ tên để một nút được gán cho máy khách.

Được viết bằng C ++, chúng tôi đã sử dụng POCO cho việc này vì nó cho phép lập trình IO, Socket và Thread đẹp.


Có hai lỗi phát sinh khiến chúng tôi khó chịu và khiến chúng tôi mất rất nhiều thời gian, đó là một lỗi thực sự:

Ngẫu nhiên, một máy tính đã chia sẻ IP localhost của mình thay vì IP từ xa.

Điều này khiến các máy khách kết nối với nút trên cùng một PC hoặc các nút để kết nối với chính chúng.

Làm thế nào chúng ta xác định điều này? Khi chúng tôi cải thiện đầu ra trong máy chủ tên, chúng tôi đã phát hiện ra sau đó khi chúng tôi khởi động lại các máy tính mà tập lệnh của chúng tôi để xác định IP đưa ra là sai. Ngẫu nhiên, thiết bị lo được liệt kê đầu tiên thay vì thiết bị eth0 ... Thực sự ngu ngốc. Vì vậy, bây giờ chúng tôi đã mã hóa để yêu cầu nó từ eth0 vì điều này được chia sẻ giữa tất cả các máy tính của trường đại học ...


Và bây giờ một điều khó chịu hơn:

Ngẫu nhiên, luồng gói sẽ tạm dừng ngẫu nhiên.
Khi khách hàng tiếp theo kết nối, nó sẽ tiếp tục ...

Điều này xảy ra thực sự ngẫu nhiên và vì có nhiều máy tính liên quan nên việc gỡ lỗi vấn đề này trở nên khó chịu hơn, các máy tính của trường đại học không cho phép chúng tôi chạy Wireshark trên những máy đó để chúng tôi đoán xem vấn đề nằm ở phía gửi hay nhận bên.

Với rất nhiều đầu ra trong mã, chúng tôi chỉ giả định rằng việc gửi các lệnh sẽ ổn,
điều này khiến chúng tôi tự hỏi vấn đề thực sự ở đâu ... Có vẻ như cách các cuộc thăm dò của POCO là sai và thay vào đó chúng tôi nên kiểm tra các ký tự có sẵn trên ổ cắm đến.

Chúng tôi đã giả định rằng điều này hoạt động như các thử nghiệm đơn giản hơn trong một nguyên mẫu liên quan đến ít gói hơn không gây ra vấn đề này, vì vậy điều này khiến chúng tôi chỉ cho rằng tuyên bố thăm dò ý kiến ​​đang hoạt động nhưng ... Không phải vậy. :-(


Bài học kinh nghiệm:

  • Đừng đưa ra các giả định ngu ngốc như thứ tự của các thiết bị mạng.

  • Các khung không phải lúc nào cũng thực hiện công việc của họ (cả thực thi hoặc tài liệu).

  • Cung cấp đủ đầu ra trong mã, nếu không được phép, hãy chắc chắn ghi nhật ký chi tiết mở rộng vào một tệp.

  • Khi mã chưa được kiểm tra đơn vị (vì quá khó), đừng cho rằng mọi thứ hoạt động.


1
Giải quyết các vấn đề về mạng mà không có wireshark (hoặc công cụ tương tự) là anh hùng trong / của iteslf.
Evan Plaice

2

Tôi vẫn đang trong quá trình săn lỗi khó khăn nhất. Đó là một trong những điều đó đôi khi ở đó và đôi khi không phải là lỗi. Đó là lý do tại sao tôi ở đây, lúc 6:10 sáng ngày hôm sau.

Lý lịch:

  • Bối cảnh: Ngôn ngữ, Ứng dụng, Môi trường, v.v.
    • Hệ điều hành thương mại PHP
  • Làm thế nào là lỗi được xác định?
    • Thứ tự ngẫu nhiên hoạt động một phần theo cách ngẫu nhiên thất bại và chuyển hướng các vấn đề
  • Ai hoặc cái gì xác định lỗi?
    • Khách hàng và vấn đề chuyển hướng là rõ ràng
  • Làm thế nào phức tạp đã tái tạo lỗi?
    • Tôi chưa thể tái sản xuất, nhưng khách hàng đã có thể.

Cuộc săn lùng.

  • Kế hoạch của bạn là gì?
    • Thêm mã gỡ lỗi, điền thứ tự, phân tích dữ liệu, lặp lại
  • Những khó khăn bạn đã gặp phải?
    • Thiếu các vấn đề lặp lại và mã khủng khiếp
  • Mã vi phạm cuối cùng đã được tìm thấy như thế nào?
    • rất nhiều mã vi phạm đã được tìm thấy .. chỉ không chính xác những gì tôi cần.

Việc giết chóc.

  • Làm thế nào phức tạp là sửa chữa?
    • rất
  • Làm thế nào bạn xác định phạm vi của sửa chữa?
    • không có phạm vi ... nó ở khắp mọi nơi
  • Có bao nhiêu mã đã tham gia vào việc sửa chữa?
    • Tất cả? Tôi không nghĩ rằng có một tập tin bị ảnh hưởng

Hậu họa.

  • Nguyên nhân gốc rễ là gì? tràn bộ đệm, vv
    • thực hành mã hóa xấu
  • Nguyên nhân gốc rễ từ 30.000 ft là gì?
    • Tôi thà không nói ...
  • Quá trình cuối cùng mất bao lâu?
    • mãi mãi và một ngày
  • Có bất kỳ tính năng nào bị ảnh hưởng xấu bởi bản sửa lỗi không?
    • đặc tính? hay nó là một con bọ nhỉ?
  • Những phương pháp, công cụ, động lực nào bạn thấy đặc biệt hữu ích? ... Vô dụng khủng khiếp?
  • Nếu bạn có thể làm lại tất cả? ............
    • ctrl + một Del

Nếu lý do là "thực hành mã hóa xấu", bạn có thể muốn thảo luận với sếp của mình nếu đây là thời điểm tốt để sửa đổi các thực hành mã hóa của nhóm của bạn và có thể giới thiệu đánh giá ngang hàng?

2

Tôi đã phải sửa một số nội dung đồng thời khó hiểu cuối cùng, nhưng lỗi vẫn nổi bật nhất đối với tôi là trong một trò chơi dựa trên văn bản mà tôi đã viết trong hội đồng PDP-11 cho bài tập về nhà. Nó dựa trên Trò chơi Cuộc sống của Conway và vì một lý do kỳ lạ, một phần lớn thông tin bên cạnh lưới điện liên tục bị ghi đè lên thông tin không nên có ở đó. Logic cũng khá đơn giản, vì vậy nó rất khó hiểu. Sau khi đi qua nó một loạt lần để khám phá lại rằng tất cả logic là chính xác, tôi đột nhiên nhận thấy vấn đề là gì. Thứ này:.

Trong PDP-11, chấm nhỏ này bên cạnh một số làm cho nó có cơ sở 10 thay vì 8. Nó nằm cạnh một số giới hạn một vòng lặp được cho là giới hạn trong lưới, có kích thước được xác định với cùng một số nhưng ở cơ sở số 8.

Nó vẫn nổi bật đối với tôi vì số lượng thiệt hại như một bổ sung kích thước 4 pixel nhỏ như vậy gây ra. Vậy kết luận là gì? Không mã trong lắp ráp PDP-11.


2

Chương trình khung chính đã ngừng hoạt động mà không có lý do

Tôi chỉ đăng điều này cho một câu hỏi khác. Xem bài ở đây

Nó xảy ra vì họ đã cài đặt một phiên bản mới hơn của trình biên dịch trên Main-Frame.

Cập nhật 06/11/13: (Câu trả lời gốc đã bị xóa bởi OP)

Tôi đã sử dụng ứng dụng khung chính này. Một ngày nọ, khi trời trong xanh, nó ngừng hoạt động. Đó là ... nó chỉ dừng lại.

Công việc của tôi là làm cho nó hoạt động nhanh nhất có thể. Mã nguồn đã không được sửa đổi trong hai năm, nhưng đột nhiên nó chỉ dừng lại. Tôi đã cố gắng biên dịch mã và nó đã bị hỏng trên dòng XX. Tôi nhìn vào dòng XX và tôi không thể biết điều gì sẽ khiến dòng XX bị phá vỡ. Tôi yêu cầu thông số kỹ thuật chi tiết cho ứng dụng này và không có thông tin nào. Dòng XX không phải là thủ phạm.

Tôi đã in mã ra và bắt đầu xem xét nó từ trên xuống. Tôi bắt đầu tạo ra một sơ đồ về những gì đang diễn ra. Mã này rất phức tạp, tôi thậm chí không thể hiểu được nó. Tôi đã từ bỏ cố gắng để lưu đồ nó. Tôi sợ thực hiện các thay đổi mà không biết sự thay đổi đó sẽ ảnh hưởng đến phần còn lại của quá trình như thế nào, đặc biệt vì tôi không có chi tiết về những gì ứng dụng đã làm.

Vì vậy, tôi quyết định bắt đầu ở đầu mã nguồn và thêm whitespce và phanh dòng để làm cho mã dễ đọc hơn. Tôi nhận thấy, trong một số trường hợp, có những điều kiện kết hợp giữa AND và OR và nó không thể phân biệt rõ ràng giữa dữ liệu nào đang được ANDed và dữ liệu nào đang được OR. Vì vậy, tôi bắt đầu đặt dấu ngoặc đơn xung quanh các điều kiện AND và OR để làm cho chúng dễ đọc hơn.

Khi tôi dần dần dọn dẹp nó, tôi sẽ định kỳ lưu công việc của mình. Tại một thời điểm tôi đã cố gắng biên dịch mã và một điều kỳ lạ xảy ra. Lỗi đã nhảy qua dòng mã ban đầu và bây giờ đã xuống sâu hơn. Vì vậy, tôi tiếp tục, bỏ qua các điều kiện AND và OR bằng parens. Khi tôi đã hoàn thành việc làm sạch nó, nó hoạt động. Đi hình.

Sau đó tôi quyết định ghé thăm cửa hàng hoạt động và hỏi họ xem gần đây họ có cài đặt bất kỳ thành phần mới nào trên khung chính không. Họ nói có, gần đây chúng tôi đã nâng cấp trình biên dịch. Hừm.

Nó chỉ ra rằng trình biên dịch cũ đánh giá biểu thức từ trái sang phải bất kể. Phiên bản mới của trình biên dịch cũng đã đánh giá các biểu thức từ trái sang phải nhưng mã mơ hồ có nghĩa là không thể giải quyết được sự kết hợp không rõ ràng giữa AND và OR.

Bài học tôi học được từ điều này ... LUÔN LUÔN, LUÔN LUÔN, LUÔN LUÔN sử dụng parens để tách các điều kiện VÀ điều kiện HOẶC khi chúng được sử dụng để kết hợp với nhau.


bài đăng liên kết của bạn đã bị xóa - bạn có phiền cập nhật câu trả lời không?
gnat

1
@gnat - Tìm thấy nó trên archive.org :)
Michael Riley - AKA Gunny

1

Lý lịch:

  • Bối cảnh: Máy chủ Web (C ++) cho phép khách hàng tự đăng ký
  • Lỗi: Khi yêu cầu trang, đơn giản là nó sẽ không trả lời, toàn bộ trang trại và các quy trình sẽ bị giết (và khởi chạy lại) vì chúng mất quá nhiều thời gian (chỉ cho phép vài giây) để phục vụ trang
  • Một số người dùng đã phàn nàn, nhưng nó cực kỳ rời rạc nên hầu như không được chú ý (mọi người chỉ có xu hướng nhấn "Làm mới" khi một trang không được phục vụ). Chúng tôi đã nhận thấy các bãi lõi mặc dù;)
  • Chúng tôi thực sự không bao giờ quản lý để sao chép trong môi trường địa phương của chúng tôi, lỗi xuất hiện một vài lần trong các hệ thống Kiểm tra nhưng không bao giờ xuất hiện trong Kiểm tra hiệu suất ??

Cuộc săn lùng.

  • Kế hoạch: Chà, vì chúng tôi có các bãi chứa bộ nhớ và nhật ký, chúng tôi muốn phân tích chúng. Vì nó đã ảnh hưởng đến toàn bộ trang trại và chúng tôi đã có một số vấn đề về cơ sở dữ liệu trong quá khứ, chúng tôi đã nghi ngờ cơ sở dữ liệu (DB đơn cho một số máy chủ)
  • Khó khăn: Một bãi chứa máy chủ đầy đủ là rất lớn, và vì vậy chúng bị xóa khá thường xuyên (không hết dung lượng), vì vậy chúng tôi phải nhanh chóng lấy một cái khi nó xảy ra ... Chúng tôi vẫn kiên trì. Các bãi chứa cho thấy các ngăn xếp khác nhau (không bao giờ có bất kỳ công cụ DB nào, rất nhiều cho điều đó), nó đã thất bại trong khi tự chuẩn bị trang (không phải trong các tính toán trước đó) và xác nhận những gì các bản ghi hiển thị, việc chuẩn bị trang đôi khi sẽ mất nhiều thời gian, thậm chí mặc dù nó chỉ là một công cụ mẫu cơ bản với dữ liệu được tính toán trước (MVC truyền thống)
  • Bắt đầu với nó: Sau một số mẫu khác và một số suy nghĩ, chúng tôi nhận ra rằng thời gian đã được đọc dữ liệu từ ổ cứng (mẫu trang). Vì nó liên quan đến toàn bộ trang trại, chúng tôi lần đầu tiên tìm kiếm các công việc theo lịch trình (crontab, đợt) nhưng thời gian không bao giờ khớp từ lần này đến lần khác ... Cuối cùng tôi nhận ra rằng điều này luôn xảy ra vài ngày trước khi kích hoạt phiên bản mới của phần mềm và tôi đã có một Ahah! Khoảnh khắc ... đó là do sự phân phối của phần mềm! Việc cung cấp vài trăm megabyte (được nén) có thể ảnh hưởng đến hiệu suất đĩa: / Tất nhiên việc phân phối được tự động hóa và lưu trữ được đẩy đến tất cả các máy chủ cùng một lúc (phát đa hướng).

Việc giết chóc.

  • Fix Complexity: chuyển sang các mẫu đã biên dịch
  • Mã bị ảnh hưởng: không có, một thay đổi đơn giản trong quá trình xây dựng

Hậu họa.

  • Nguyên nhân gốc rễ: vấn đề hoạt động hoặc thiếu kế hoạch chuyển tiếp :)
  • Timescale: phải mất nhiều tháng để theo dõi, mất vài ngày để sửa chữa và thử nghiệm, một vài tuần để kiểm tra và triển khai QA và Hiệu suất - không vội vàng, vì chúng tôi biết rằng việc triển khai bản sửa lỗi sẽ gây ra lỗi ... và không có gì khác ... thật là hư hỏng!
  • Tác dụng phụ bất lợi: không thể chuyển đổi các mẫu trong thời gian chạy khi chúng được nướng trong mã được phân phối, mặc dù vậy, chúng tôi đã không sử dụng tính năng này nhiều, vì nói chung việc chuyển đổi các mẫu có nghĩa là bạn đã có nhiều dữ liệu hơn để sử dụng. chủ yếu là đủ cho những thay đổi bố cục "nhỏ".
  • Phương pháp, công cụ: gdb+ giám sát! Chỉ cần chúng tôi dành thời gian để nghi ngờ đĩa, và sau đó xác định nguyên nhân của sự tăng đột biến của hoạt động trên biểu đồ giám sát ...
  • Lần tới: coi tất cả IO là bất lợi!

1

Người khó nhất không bao giờ bị giết bởi vì nó không bao giờ có thể được sao chép ngoài môi trường sản xuất đầy đủ với nhà máy hoạt động.

Kẻ điên rồ nhất tôi đã giết:

Các bản vẽ được in vô nghĩa!

Tôi nhìn vào mã và tôi không thể thấy gì. Tôi kéo một công việc ra khỏi hàng đợi máy in và kiểm tra nó, nó có vẻ tốt. . .

Quay lại mã, vấn đề vẫn còn đó.

Cuối cùng tôi tự làm một tập tin đơn giản và gửi nó đến máy in - vô nghĩa. Hóa ra đó không phải là lỗi của tôi mà là chính máy in. Công ty bảo trì đã đưa nó lên phiên bản mới nhất khi họ đang sửa một thứ khác và phiên bản mới nhất đó có lỗi. Làm cho họ hiểu rằng họ đã loại bỏ chức năng quan trọng và phải đưa nó trở lại phiên bản trước đó khó hơn tìm ra lỗi.

Một thứ thậm chí còn khó chịu hơn nhưng vì nó chỉ ở trên hộp của tôi nên tôi không đặt ở vị trí đầu tiên:

Mã Borland Pascal, DPMI để xử lý một số API không được hỗ trợ. Chạy nó, đôi khi nó hoạt động, thường nó đã bùng nổ để cố gắng đối phó với một con trỏ không hợp lệ. Tuy nhiên, nó không bao giờ tạo ra một kết quả sai như bạn mong đợi từ việc dẫm lên một con trỏ.

Gỡ lỗi - nếu tôi thực hiện một lần mã, nó sẽ luôn hoạt động chính xác, nếu không thì nó vẫn không ổn định như trước. Kiểm tra luôn cho thấy các giá trị đúng.

Thủ phạm: Có hai.

1) Mã thư viện của Borland có một lỗi lớn: Con trỏ chế độ thực đang được lưu trữ trong các biến con trỏ trong chế độ được bảo vệ. Vấn đề là hầu hết các con trỏ chế độ thực có địa chỉ phân đoạn không hợp lệ trong chế độ được bảo vệ và khi bạn cố gắng sao chép con trỏ, nó đã tải nó vào một cặp đăng ký và sau đó lưu nó.

2) Trình gỡ lỗi sẽ không bao giờ nói bất cứ điều gì về tải không hợp lệ như vậy trong chế độ một bước. Tôi không biết những gì nó đã làm trong nội bộ nhưng những gì được trình bày cho người dùng trông hoàn toàn chính xác. Tôi nghi ngờ rằng nó không thực sự thực hiện hướng dẫn mà thay vào đó mô phỏng nó.


1

Đây chỉ là một lỗi rất đơn giản mà bằng cách nào đó tôi đã biến thành cơn ác mộng đối với tôi.

Bối cảnh: Tôi đang làm việc để tạo ra Hệ điều hành của riêng mình. Gỡ lỗi là rất khó (báo cáo theo dõi là tất cả những gì bạn có thể có, và đôi khi thậm chí là không)

Lỗi: Thay vì thực hiện hai chuyển đổi luồng tại usermode, thay vào đó sẽ là lỗi bảo vệ chung.

Cuộc săn lỗi: Tôi đã dành khoảng một hoặc hai tuần để khắc phục vấn đề này. Chèn báo cáo dấu vết ở khắp mọi nơi. Kiểm tra mã lắp ráp được tạo ra (từ GCC). In ra từng giá trị tôi có thể.

Vấn đề: Ở đâu đó sớm trong cuộc săn bọ, tôi đã đặt một hlthướng dẫn trong crt0. Crt0 về cơ bản là những gì bootstraps một chương trình người dùng để sử dụng trong một hệ điều hành. Điều nàyhltHướng dẫn gây ra GPF khi được thực thi từ chế độ người dùng. Tôi đặt nó ở đó và về cơ bản quên nó. (ban đầu sự cố là lỗi tràn bộ đệm hoặc lỗi cấp phát bộ nhớ)

Cách khắc phục: Xóa hlthướng dẫn :) Sau khi gỡ bỏ, mọi thứ đều hoạt động trơn tru.

Những gì tôi học được: Khi cố gắng gỡ lỗi một vấn đề, đừng để mất dấu vết của các bản sửa lỗi bạn thử. Làm khác thường xuyên so với phiên bản kiểm soát nguồn ổn định mới nhất và xem những gì bạn đã thay đổi gần đây khi không có gì khác hoạt động

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.