Xcode ไม่แสดงบรรทัดที่ทำให้เกิดข้อขัดข้อง


126

ทุกครั้งที่แอปของฉันขัดข้อง Xcode จะไฮไลต์การเรียก UIApicationMain () ในฟังก์ชัน main () เป็นบรรทัดที่ทำให้เกิดข้อขัดข้อง ในบางกรณีที่เคยเป็นเรื่องปกติ (เช่นความผิดพลาดในการแบ่งส่วน) แต่ความผิดพลาดที่ฉันพยายามจัดการคือ SIGABRT ธรรมดาที่มีข้อมูลโดยละเอียดที่บันทึกไว้ในคอนโซล:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary setObject:forKey:]: attempt to insert nil value (key: Date)'

Xcode ใช้เพื่อแสดงบรรทัดที่เหมาะสมกับ SDK รุ่นเก่า แต่เนื่องจากฉันอัปเกรดเป็น Xocde 4.2 ที่เปลี่ยนไป เห็นได้ชัดว่า Xcode รู้แน่ชัดว่าอะไรทำให้เกิดความผิดพลาด (หรืออาจจะรู้) แต่ก็ยังไม่แสดงเส้นที่แท้จริง มีวิธีแก้ไขหรือวิธีแก้ปัญหาสำหรับสิ่งนี้หรือไม่?


2
คุณกำลังรวบรวม Release หรือไม่ หากเป็นเช่นนั้นให้ลองตั้งค่าโครงร่างเป็น Debug
epatel

นอกจากนี้ยังอาจเป็นไปได้ว่า xib บางตัวไม่ดีทำให้โปรแกรมขัดข้องในที่ที่ไม่ได้ใช้ซอร์สโค้ดของคุณเองดังนั้นจึงไม่แสดงไฟล์ใด ๆ ข้อผิดพลาดนี้อธิบายถึงปัญหาของคีย์พจนานุกรมชื่อ "วันที่"
epatel

1
Apple ควรจ้างผู้ทดสอบมากกว่านี้)
Amr Lotfy

คำตอบ:


301

นอกจากนี้คุณควรตรวจสอบให้แน่ใจว่าคุณได้กำหนดจุดพักไว้สำหรับข้อยกเว้นทั้งหมด สิ่งนี้จะทำให้ Xcode หยุดที่บรรทัดที่มีข้อยกเว้นเกิดขึ้น ดำเนินการต่อไปนี้ [ใน Xcode 4]:

  1. ใน Project Navigator ทางด้านซ้ายของ Xcode ให้คลิกที่ตัวนำทางเบรกพอยต์ (เกือบสุดทางด้านขวามือของแถบปุ่มด้านบนไอคอนจะมีลักษณะเป็นลูกศรขวาอ้วน)

  2. ที่ด้านล่างของตัวนำทางให้คลิกปุ่ม "+"

  3. คลิก "Add Exception Breakpoint"

  4. จะมีการสร้างเบรกพอยต์ใหม่ ควรกำหนดค่าตามความจำเป็น แต่คุณสามารถปรับเปลี่ยนพฤติกรรมได้

  5. เรียกใช้โครงการของคุณและสร้างข้อยกเว้นใหม่

นอกจากนี้คุณยังกล่าวว่าคุณเชื่อมโยงกับไลบรารี / เฟรมเวิร์กของบุคคลที่สาม หากข้อยกเว้นเกิดขึ้นภายในเฟรมเวิร์กเหล่านั้นคุณจะต้องพบกับความยากลำบากเนื่องจากโค้ดถูกคอมไพล์และ Xcode ไม่สามารถแสดงบรรทัดที่ทำให้เกิดข้อยกเว้นได้ หากเป็นกรณีนี้และคุณมั่นใจว่าคุณใช้ไลบรารีอย่างถูกต้องคุณควรส่งรายงานข้อบกพร่องไปยังผู้ดูแลของไลบรารีเหล่านั้น


4
ฉันเป็น noob และพัฒนาเกือบหนึ่งเดือนโดยไม่มีสิ่งนี้ ... สิ่งนี้เปลี่ยนชีวิตของฉัน
Jonny Burger

4
เพื่อนของฉันลงทะเบียนบัญชี SO เพียงเพื่อโหวตโพสต์นี้
Alex Spencer

1
สิ่งนี้เรียกว่าครึ่งหนึ่งของแอปเปิ้ลในหนังสือของฉัน
ChuckKelly

1
ทำสิ่งนี้แล้วแต่ยังหาไม่ได้ว่ามันเรียกว่า length บน null :(
Shereef Marzouk

1
วิธีนี้ใช้ได้ผล แต่ข้อเสียคือไม่แสดงรายละเอียดของข้อยกเว้นในคอนโซลการแก้ปัญหาอีกต่อไป ดังนั้นฉันจึงสามารถปิดเบรกพอยต์นี้และดูรายละเอียดและการติดตามของข้อยกเว้น แต่ไม่ใช่ว่ามันเกิดขึ้นที่ไหนหรือเปิดเพื่อดูว่ามันเกิดขึ้นที่ไหน แต่ไม่ใช่ว่าทำไม ใครรู้วิธีมีทั้งสอง?
Gabriel Jensen

27

เพียงทำตามคำแนะนำในคำตอบ StackOverflow นี้:

เปิดใช้งาน Zombies

โดยพื้นฐานแล้วคุณต้อง "เปิดใช้งานซอมบี้" จากนั้น Xcode ควรแตกที่บรรทัดใดที่ทำให้เกิดปัญหา

ใส่คำอธิบายภาพที่นี่

(เป็นเรื่องที่น่าตกใจอย่างยิ่งที่แม้ในปี 2017 Xcode จะยังคงปิดการใช้งานนี้โดยปริยายทำไมคุณไม่ต้องการเห็นบรรทัดที่ทำให้เกิดปัญหาและ " Enable Zombie Objects " จริงหรือ! ผู้เขียน Xcode จริงๆ เชื่อว่านี่เป็นชื่อที่มีประโยชน์ซึ่งจะทำให้รู้สึกถึงนักพัฒนาหน้าใหม่หรือไม่เป็นที่น่าหดหู่ว่าคะแนนของ Xcode แย่แค่ไหนปีแล้วปีเล่าใน App Store ไม่มีใครฟัง ... )


6
Xcode เป็นสภาพแวดล้อมการเขียนโปรแกรมที่แย่ที่สุดที่ฉันเคยใช้มา
นักเรียน

สิ่งที่ฉันคิดว่าน่าสนใจ (ในฐานะนักพัฒนา Visual Studio) คือจำนวนนักพัฒนา Xcode ที่ฉันได้พบซึ่งยืนยันว่า Xcode เป็นสภาพแวดล้อมที่ดีที่สุดที่พวกเขาเคยใช้ ตรรกะเป็นมิตรและเป็นประโยชน์ .. แต่มีนิสัยใจคอเล็กน้อย แม้ตอนนี้ในเดือนพฤศจิกายน 2019 Xcode มีคะแนน App Store 3.1 โดยคนส่วนใหญ่ให้คะแนน 5 ดาวหรือ 1 ดาว ไม่มีใครฟัง ....
Mike Gledhill

10

แก้ไขโครงการปัจจุบันและเปิดใช้งานNSZombieEnabled, และMallocStackLogging guard mallocจากนั้นเมื่อแอปของคุณขัดข้องให้พิมพ์สิ่งนี้ในคอนโซล gdb:

(gdb) info malloc-history 0x543216

แทนที่0x543216ด้วยที่อยู่ของวัตถุที่ทำให้เกิดNSInvalidArgumentExceptionและควรให้การติดตามสแต็กที่มีประโยชน์มากขึ้นโดยแสดงบรรทัดของรหัสของคุณที่ทำให้เกิดข้อขัดข้อง


1
ฉันลองแล้วและพบข้อผิดพลาด: "ข้อมูล" ไม่ใช่คำสั่งที่ถูกต้อง คำแนะนำใด ๆ?
achi

@EliGregory ตรวจสอบให้แน่ใจว่าดีบักเกอร์ของคุณตั้งค่าเป็น gdb ไม่ใช่ lldb เริ่มต้น คุณสามารถเปลี่ยนได้ในเมนู Edit Scheme ภายใต้ส่วน run
chown

2

ฉันได้เห็นพฤติกรรมนี้ในโค้ดที่ปรับให้เหมาะสมอย่างมาก การตรวจสอบปรับแต่งระดับการเพิ่มประสิทธิภาพของเป้าหมายของคุณและของบุคคลที่สามอาจช่วยได้ (LLVM 3.0 การตั้งค่าระดับการเพิ่มประสิทธิภาพ)

คุณกำลังสร้างสัญลักษณ์การดีบักหรือไม่?


ตกลง หากคุณกำลังพยายามแก้ไขข้อบกพร่องระดับการเพิ่มประสิทธิภาพจะต้องถูกตั้งค่าเป็น 0 (ไม่มีการเพิ่มประสิทธิภาพ) ในการตั้งค่าการสร้างของคุณ
Carter

1

ฉันเขียนโค้ดเพื่อสร้างความผิดพลาดของดัชนีนอกขอบเขต ต่อไปนี้เป็นข้อยกเว้นที่เกิดขึ้น

2017-01-07 04:02:57.606 testABC[1694:52966] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSSingleObjectArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010e85cd4b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x000000010e2be21e objc_exception_throw + 48
    2   CoreFoundation                      0x000000010e8b5c2f -[__NSSingleObjectArrayI objectAtIndex:] + 111
    3   testABC                             0x000000010dce962d -[ViewController ComplexFunction] + 61
    4   testABC                             0x000000010dce95db -[ViewController thirdFunction] + 43
    5   testABC                             0x000000010dce959b -[ViewController secondFunction] + 43
    6   testABC                             0x000000010dce955b -[ViewController firstFinction] + 43
    7   testABC                             0x000000010dce96c2 -[ViewController viewDidAppear:] + 50
    8   UIKit                               0x000000010ee28a6c -[UIViewController _setViewAppearState:isAnimating:] + 945
    9   UIKit                               0x000000010ee2b7da __64-[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:]_block_invoke + 42
    10  UIKit                               0x000000010ee29ac4 -[UIViewController _executeAfterAppearanceBlock] + 86
    11  UIKit                               0x000000010ec8d77c _runAfterCACommitDeferredBlocks + 653
    12  UIKit                               0x000000010ec7a273 _cleanUpAfterCAFlushAndRunDeferredBlocks + 566
    13  UIKit                               0x000000010ec9d757 __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke_2 + 194
    14  CoreFoundation                      0x000000010e8016ac __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    15  CoreFoundation                      0x000000010e7e66f4 __CFRunLoopDoBlocks + 356
    16  CoreFoundation                      0x000000010e7e5e65 __CFRunLoopRun + 901
    17  CoreFoundation                      0x000000010e7e5884 CFRunLoopRunSpecific + 420
    18  GraphicsServices                    0x00000001126d9a6f GSEventRunModal + 161
    19  UIKit                               0x000000010ec80c68 UIApplicationMain + 159
    20  testABC                             0x000000010dce99df main + 111
    21  libdyld.dylib                       0x000000011174968d start + 1
    22  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

หากคุณอ่านอย่างละเอียด First Throw call stack

0   CoreFoundation              0x000000010e85cd4b __exceptionPreprocess + 171
1   libobjc.A.dylib             0x000000010e2be21e objc_exception_throw + 48

0 and 1 คือกระบวนการของระบบหลังจากเกิดความผิดพลาด

 2   CoreFoundation             0x000000010e8b5c2f -[__NSSingleObjectArrayI objectAtIndex:] + 111

2 คือเส้นที่ทำให้เกิดข้อยกเว้น

3   testABC                     0x000000010dce962d -[ViewController ComplexFunction] + 61

3บอกให้คุณทราบว่าชื่อคลาส ( ViewController) และฟังก์ชัน naem ( ComplexFunction) ซึ่งมีข้อยกเว้นเกิดขึ้น


4
เอ่อไม่เป็นไร คุณพูดถูก แต่นี่เป็นมิตรหรือไม่? ในสภาพแวดล้อมการพัฒนาที่ทันสมัย ​​(1990 เป็นต้นไป) เมื่อมีข้อยกเว้นเกิดขึ้นคุณจะเข้าสู่บรรทัดที่ทำให้เกิดปัญหา ในขณะที่ Xcode ... ดี ... ให้การติดตามสแต็กเช่นนี้ แม้แต่ Turbo Pascal ก็ไม่ล้าสมัย !!!
Mike Gledhill

4
เป็นเรื่องน่าขันที่ บริษัท ซึ่งเป็นที่รู้จักกันดีในเรื่อง "ประสบการณ์การใช้งานที่ดีที่สุด" ไม่ทราบว่านักพัฒนาทุกคนในช่วง 20 ปีที่ผ่านมาคุ้นเคยกับการเห็นหมายเลขบรรทัดที่มีข้อยกเว้นเกิดขึ้นและไม่ได้อยู่ในแอสเซมเบลอร์ ฉันจะบ้าเหรอ? ทุกภาษาที่ฉันเคยทำงานมาทั้งชีวิตให้หมายเลขบรรทัด แม้แต่ C หรือ C ++
mylovemhz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.