Các ngoại lệ “EXC_BREAKPOINT (SIGTRAP)” có phải do gỡ lỗi các điểm ngắt không?


82

Tôi có một ứng dụng đa luồng rất ổn định trên tất cả các máy thử nghiệm của tôi và dường như ổn định đối với hầu hết mọi người dùng của tôi (dựa trên không có khiếu nại về sự cố). Tuy nhiên, ứng dụng thường xuyên gặp sự cố đối với một người dùng, người đủ tốt để gửi báo cáo sự cố. Tất cả các báo cáo sự cố (~ 10 báo cáo liên tiếp) về cơ bản trông giống hệt nhau:

Date/Time:       2010-04-06 11:44:56.106 -0700
OS Version:      Mac OS X 10.6.3 (10D573)
Report Version:  6

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000002, 0x0000000000000000
Crashed Thread:  0  Dispatch queue: com.apple.main-thread

Thread 0 Crashed:  Dispatch queue: com.apple.main-thread
0   com.apple.CoreFoundation        0x90ab98d4 __CFBasicHashRehash + 3348
1   com.apple.CoreFoundation        0x90adf610 CFBasicHashRemoveValue + 1264
2   com.apple.CoreText              0x94e0069c TCFMutableSet::Intersect(__CFSet const*) const + 126
3   com.apple.CoreText              0x94dfe465 TDescriptorSource::CopyMandatoryMatchableRequest(__CFDictionary const*, __CFSet const*) + 115
4   com.apple.CoreText              0x94dfdda6 TDescriptorSource::CopyDescriptorsForRequest(__CFDictionary const*, __CFSet const*, long (*)(void const*, void const*, void*), void*, unsigned long) const + 40
5   com.apple.CoreText              0x94e00377 TDescriptor::CreateMatchingDescriptors(__CFSet const*, unsigned long) const + 135
6   com.apple.AppKit                0x961f5952 __NSFontFactoryWithName + 904
7   com.apple.AppKit                0x961f54f0 +[NSFont fontWithName:size:] + 39

(.... thêm văn bản sau)

Đầu tiên, tôi đã dành một thời gian dài để điều tra [NSFont fontWithName: size:]. Tôi nhận ra rằng có thể phông chữ của người dùng đã bị hỏng bằng cách nào đó, vì vậy [NSFont fontWithName: size:] đã yêu cầu một cái gì đó không tồn tại và không thành công vì lý do đó. Tôi đã thêm một loạt mã bằng cách sử dụng [[NSFontManager sharedFontManager] availableFontNamesWithTraits: NSItalicFontMask] để kiểm tra trước về tính khả dụng của phông chữ. Đáng buồn thay, những thay đổi này không khắc phục được sự cố.

Bây giờ tôi nhận thấy rằng tôi đã quên xóa một số điểm ngắt gỡ lỗi, bao gồm _NSLockError, [NSException raise] và objc_exception_throw. Tuy nhiên, ứng dụng chắc chắn được xây dựng bằng cách sử dụng "Bản phát hành" làm cấu hình bản dựng đang hoạt động. Tôi giả sử rằng việc sử dụng cấu hình "Release" ngăn cản việc thiết lập bất kỳ điểm ngắt nào - nhưng sau đó, tôi không chắc chắn chính xác cách hoạt động của các điểm ngắt hoặc liệu chương trình có cần được chạy từ bên trong gdb để các điểm ngắt có bất kỳ tác dụng nào hay không.

Câu hỏi của tôi là: việc tôi để lại các điểm ngắt có thể là nguyên nhân gây ra sự cố mà người dùng quan sát thấy không? Nếu vậy, tại sao các điểm ngắt lại gây ra sự cố chỉ cho một người dùng này? Nếu không, có ai khác gặp sự cố tương tự với [NSFont fontWithName: size:] không?

Tôi có thể sẽ chỉ thử xóa các điểm ngắt và gửi lại cho người dùng, nhưng tôi không chắc mình còn lại bao nhiêu tiền với người dùng đó. Và tôi muốn hiểu một cách tổng quát hơn liệu việc đặt các điểm ngắt có thể gây ra sự cố hay không (khi ứng dụng được tạo bằng cấu hình "Bản phát hành").

Câu trả lời:


188

Các ngoại lệ “EXC_BREAKPOINT (SIGTRAP)” có phải do gỡ lỗi các điểm ngắt không?

Không. Thực ra thì ngược lại: Một SIGTRAP (bẫy dấu vết) sẽ khiến trình gỡ lỗi phá vỡ (làm gián đoạn) chương trình của bạn, giống như cách một điểm ngắt thực tế sẽ làm. Nhưng đó là bởi vì trình gỡ lỗi luôn bị hỏng khi có sự cố và SIGTRAP (giống như một số tín hiệu khác ) là một loại sự cố.

Các SIGTRAP nói chung là do các NSExceptions được ném ra, nhưng không phải lúc nào cũng vậy — bạn thậm chí có thể tự nâng trực tiếp một NSExceptions .

Bây giờ tôi nhận thấy rằng tôi đã quên xóa một số điểm ngắt gỡ lỗi, bao gồm _NSLockError, [NSException raise] và objc_exception_throw.

Đó không phải là những điểm ngắt. Hai trong số chúng là các hàm và -[NSException raise]là một phương thức.

Ý bạn là bạn đặt các điểm ngắt trên các hàm đó và phương pháp đó?

Tôi cho rằng việc sử dụng cấu hình "Phát hành" ngăn cản việc thiết lập bất kỳ điểm ngắt nào--

Không.

Các cấu hình là cấu hình xây dựng . Chúng ảnh hưởng đến cách Xcode xây dựng các ứng dụng của bạn.

Các điểm ngắt không phải là một phần của bản dựng; bạn đặt chúng trong trình gỡ lỗi. Chúng chỉ tồn tại, chỉ bị tấn công và chỉ dừng chương trình của bạn khi bạn chạy chương trình của mình trong trình gỡ lỗi.

Vì chúng không phải là một phần của bản dựng, nên không thể chuyển các điểm ngắt của bạn cho người dùng chỉ bằng cách cung cấp cho họ gói ứng dụng.

Tôi không chắc chính xác cách hoạt động của các điểm ngắt…

Khi chương trình của bạn chạm điểm ngắt, trình gỡ lỗi sẽ ngắt (làm gián đoạn) chương trình của bạn, từ đó bạn có thể kiểm tra trạng thái của chương trình và tiến hành cẩn thận từng bước để xem chương trình bị lỗi như thế nào.

Vì đó là trình gỡ lỗi dừng chương trình của bạn, các điểm ngắt không có tác dụng khi bạn không chạy chương trình của mình trong trình gỡ lỗi.

… Hoặc liệu chương trình có cần được chạy từ bên trong gdb để các điểm ngắt có tác dụng hay không.

Nó có. Các điểm ngắt của trình gỡ lỗi chỉ hoạt động trong trình gỡ lỗi.

Câu hỏi của tôi là: việc tôi để lại các điểm ngắt có thể là nguyên nhân gây ra sự cố mà người dùng quan sát thấy không?

Không.

Đầu tiên, như đã lưu ý, ngay cả khi các điểm ngắt này bằng cách nào đó đã được chuyển sang hệ thống của người dùng, các điểm ngắt chỉ có hiệu lực trong trình gỡ lỗi. Trình gỡ lỗi không thể dừng ở điểm ngắt nếu chương trình của bạn không chạy trong trình gỡ lỗi. Người dùng gần như chắc chắn không chạy ứng dụng của bạn trong trình gỡ lỗi, đặc biệt là vì họ gặp sự cố đăng xuất khỏi ứng dụng.

Ngay cả khi họ đã chạy ứng dụng của bạn theo trình gỡ lỗi với tất cả các breakpoint được thiết lập, một breakpoint chỉ đánh khi đạt đến chương trình của bạn mà điểm, vì vậy một trong những breakpoint chỉ có thể cháy nếu bạn hoặc Cocoa gọi _NSLockError, -[NSException raise]hoặc objc_exception_throw. Đi đến điểm đó không phải là nguyên nhân của vấn đề, nó sẽ là một triệu chứng của vấn đề.

Và nếu bạn gặp sự cố do một trong số những người đó được gọi, nhật ký sự cố của bạn sẽ có ít nhất một trong số họ có tên trong đó. Nó không.

Vì vậy, điều này không liên quan đến các điểm ngắt của bạn (máy khác, trình gỡ lỗi không liên quan) và nó không phải là ngoại lệ của Cocoa — như tôi đã đề cập, các ngoại lệ của Cocoa là một nguyên nhân gây ra SIGTRAP, nhưng chúng không phải là trường hợp duy nhất. Bạn đã gặp phải một cái khác.

Nếu không, có ai khác gặp sự cố tương tự với [NSFont fontWithName: size:] không?

Không có cách nào chúng tôi có thể biết liệu bất kỳ vấn đề nào chúng tôi gặp phải có tương tự hay không vì bạn đã cắt nhật ký sự cố. Chúng tôi không biết gì về bối cảnh vụ tai nạn xảy ra.

Điều duy nhất tốt để loại bỏ là phần “Hình ảnh nhị phân”, vì chúng tôi không có gói dSYM của bạn, có nghĩa là chúng tôi không thể sử dụng phần đó để biểu thị nhật ký sự cố.

Mặt khác, bạn có thể. Tôi đã viết một ứng dụng cho mục đích này; cung cấp nhật ký sự cố cho nó và nó sẽ tự động phát hiện gói dSYM (bạn đang giữ gói dSYM cho mọi bản phát hành mà bạn phân phối, phải không?) và khôi phục tên hàm và phương thức của bạn vào dấu vết ngăn xếp bất cứ nơi nào các hàm và phương thức của bạn xuất hiện.

Để biết thêm thông tin, hãy xem Hướng dẫn gỡ lỗi Xcode .


3
Wow, cảm ơn vì câu trả lời toàn diện. • "Ý bạn là bạn đặt các điểm ngắt trên các hàm đó ..." Đúng, ý tôi là như vậy. • "Các điểm ngắt không phải là một phần của bản dựng ... Chúng chỉ tồn tại, chỉ bị tấn công và chỉ dừng chương trình của bạn khi bạn chạy chương trình của mình trong trình gỡ lỗi" Cảm ơn, đây chính xác là những gì tôi muốn biết. • "biểu thị nhật ký sự cố ... Tôi đã viết một ứng dụng cho mục đích này" Ứng dụng tuyệt vời. Tôi thường "tượng trưng" bằng trực giác tuyệt đối - nhưng ứng dụng của bạn là cách tốt hơn! • Tôi đã kết luận rằng đây hẳn là một loại vấn đề nào đó với phông chữ của người dùng và sẽ giải quyết nó từ góc độ đó.
Dennis

7

Rất có thể người dùng này đã cài đặt phông chữ bị hỏng. Dấu vết ngăn xếp chắc chắn ủng hộ giả thuyết đó, cũng như thực tế là nó chỉ ảnh hưởng đến một người dùng.

Bạn không thể làm gì nhiều trong trường hợp đó ngoại trừ yêu cầu người dùng xóa phông chữ vi phạm, vì sự cố xảy ra diễn ra sâu trong mã của Apple.

Hãy thử yêu cầu người dùng chạy xác thực phông chữ trong Font Book. Để thực hiện việc này, khởi chạy Font Book, bấm Tất cả Phông chữ trong danh sách nguồn và sau đó chọn tất cả các phông chữ được liệt kê. Sau đó, bạn có thể chọn Xác thực Phông chữ từ menu Tệp .


1
Cảm ơn mẹo này về Font Book - Tôi biết rất ít về Font và thực sự đã có một khoảng thời gian thú vị khi xác thực phông chữ của riêng mình ... Tôi sẽ đề nghị người dùng thử điều này.
Dennis

0

Các điểm ngắt không được ghi vào hệ nhị phân. Rất tiếc là người này đã cài đặt hệ điều hành bị hỏng. Kiểm tra nhật ký bảng điều khiển để tìm thông báo dyld.


Cảm ơn cho câu trả lời nhanh chóng này! Trong Googling xung quanh vấn đề này, tôi nhận thấy rằng những người khác có EXC_BREAKPOINTS được liên kết với thông báo dyld - nhưng nhật ký sự cố của tôi không hiển thị bất kỳ thông báo nào từ dyld.
Dennis

0

Tôi đã có những lỗi giống nhau. Vì một lý do không thể giải thích được, điểm ngắt là nguyên nhân gây ra ngoại lệ EXC_BREAKPOINT . Giải pháp là loại bỏ điểm ngắt và sau đó mã hoạt động.

EXC_BREAKPOINT là một loại ngoại lệ mà trình gỡ lỗi sử dụng. Khi bạn đặt một điểm ngắt trong mã của mình, trình biên dịch sẽ chèn một ngoại lệ thuộc loại này vào mã thực thi. Khi quá trình thực thi đạt đến điểm đó, ngoại lệ sẽ được ném ra và trình gỡ lỗi sẽ bắt được nó. Sau đó, trình gỡ lỗi hiển thị mã của bạn trong dòng "điểm ngắt". Đây là cách hoạt động của trình gỡ lỗi. Nhưng trong trường hợp này, trình gỡ lỗi không xử lý ngoại lệ một cách chính xác và được trình bày như một lỗi ngoại lệ thông thường.

Tôi đã tìm thấy lỗi này hai lần trong đời:

  • một sử dụng Xcode khoảng một năm trước.
  • cái kia sử dụng Visual C ++ khoảng 15 năm trước.

Thật kỳ lạ, tôi đã gặp lỗi này mà không có bất kỳ điểm ngắt nào.
kelin

Tôi không cho biết lỗi này chỉ xảy ra với các điểm ngắt: EXC_BREAKPOINT có thể xảy ra vì nhiều lý do. Những gì tôi đang giải thích là một số trường hợp rất hiếm khi một điểm ngắt tạo ra một ngoại lệ không được xử lý.
veladan
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.