jjzjj

ios - __destroy_helper_block_ 上的 Objective-C 崩溃

coder 2023-07-25 原文

我有一个 iOS 应用程序在调用 __destroy_helper_block_253__destroy_helper_block_278 时崩溃,我不确定“destroy_helper_block”引用的是什么或者它后面的数字是什么应该指向。

有没有人对如何追踪这些崩溃可能发生的确切位置有任何指示?

这是一个回溯示例(请注意,带有 __destroy_helper_block 的行仅引用它所在的文件,而通常情况下行号也会包含在内)。

Thread : Crashed: com.apple.root.default-priority
0  libdispatch.dylib              0x000000018fe0eb2c _dispatch_semaphore_dispose + 60
1  libdispatch.dylib              0x000000018fe0e928 _dispatch_dispose + 56
2  libdispatch.dylib              0x000000018fe0e928 _dispatch_dispose + 56
3  libdispatch.dylib              0x000000018fe0c10c -[OS_dispatch_object _xref_dispose] + 60
4  Example App                    0x00000001000fe5a4 __destroy_helper_block_278 (TSExampleApp.m)
5  libsystem_blocks.dylib         0x000000018fe53908 _Block_release + 256
6  Example App                    0x00000001000fda18 __destroy_helper_block_253 (TSExampleApp.m)
7  libsystem_blocks.dylib         0x000000018fe53908 _Block_release + 256
8  libdispatch.dylib              0x000000018fe0bfd4 _dispatch_client_callout + 16
9  libdispatch.dylib              0x000000018fe132b8 _dispatch_root_queue_drain + 556
10 libdispatch.dylib              0x000000018fe134fc _dispatch_worker_thread2 + 76
11 libsystem_pthread.dylib        0x000000018ffa16bc _pthread_wqthread + 356

编辑 1:这是发生崩溃的文件中定义的 block 之一的示例(删除了特定于应用程序的代码)。

- (void)doSomethingWithCompletion:(void (^)())completion {
    void (^ExampleBlock)(NSString *) = ^{
        NSNotification *notification = [NSNotification notificationWithName:kExampleNotificationName object:nil userInfo:nil];
        [[NSNotificationCenter defaultCenter] postNotification:notification];

        if (completion) {
            completion();
        }
    };

    // Async network call that calls ExampleBlock on either success or failure below...
}

文件中还有许多其他 block ,但其中大部分是作为参数提供给方法的,而不是先定义然后再引用。

编辑 2:为上述函数添加了更多上下文。

最佳答案

堆栈跟踪的每一帧都应该为您提供有关 libDispatch 正在做什么导致崩溃的线索。从底部开始工作:

11 libsystem_pthread.dylib        0x000000018ffa16bc _pthread_wqthread
10 libdispatch.dylib              0x000000018fe134fc _dispatch_worker_thread2 + 76

这两个函数启动一个工作线程并运行它。在此过程中,它还为线程设置了一个自动释放池。

9  libdispatch.dylib              0x000000018fe132b8 _dispatch_root_queue_drain + 556

此函数表示队列销毁过程的开始。特定于线程的自动释放池被耗尽,并且在该过程中释放该特定队列引用的所有变量。因为这是 libDispatch,这意味着底层的 mach 对象和您提交的工作 block 必须离开......

7  libsystem_blocks.dylib         0x000000018fe53908 _Block_release + 256
6  Example App                    0x00000001000fda18 __destroy_helper_block_253 (TSExampleApp.m)
5  libsystem_blocks.dylib         0x000000018fe53908 _Block_release + 25
4  Example App                    0x00000001000fe5a4 __destroy_helper_block_278 (TSExampleApp.m)

这正是这里发生的事情。数字 7 是外部 block ,因为它包含一个要销毁的非平凡对象(又是另一个 block ),编译器生成了一个析构函数 (__destroy_helper_block_253) 来摆脱那个内部 block 。应用相同的逻辑,我们可以推断出内部 block 还有一点重要的破坏要做。

3  libdispatch.dylib              0x000000018fe0c10c -[OS_dispatch_object _xref_dispose] + 60
2  libdispatch.dylib              0x000000018fe0e928 _dispatch_dispose + 56
1  libdispatch.dylib              0x000000018fe0e928 _dispatch_dispose + 56

这些台词是你所有烦恼的根源。出于某种原因,您已经捕获了您正在回调的队列,或者您已经捕获了一个对象,该对象持有对队列的引用很弱,这样当它走恐龙的路时,它会带走它的队列.这会导致 libDispatch 假定队列已完成,并且它会继续解除分配,直到它到达特定于信号量的处置

0  libdispatch.dylib              0x000000018fe0eb2c _dispatch_semaphore_dispose + 60

由于没有要释放的信号量,mach 会提示到在信号量销毁时不返回 KERN_SUCCESS,这是 libDispatch 中的 fatal error 。事实上,在这种情况下它会 abort() - 嗯,技术上是 __builtin_trap(),但它们实现了相同的目标。因为没有附加调试器,所以您的应用会停止运行。

所以这就提出了一个问题:你如何解决这个问题?好吧,首先你需要找到什么,如果有的话引用了一个调度对象。你提到你正在做一些异步网络,所以那将是首先检查的地方。如果这些对象中的任何一个碰巧持有一个队列或信号量,或者引用一个持有队列或信号量的对象,并且您没有在任何这些 block 中强烈捕获它,那么当 block 与对象一起超出范围时,就会发生这种情况.

关于ios - __destroy_helper_block_ 上的 Objective-C 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23573114/

有关ios - __destroy_helper_block_ 上的 Objective-C 崩溃的更多相关文章

  1. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  2. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  3. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

  4. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  5. ruby-on-rails - Enumerator.new 如何处理已通过的 block ? - 2

    我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m

  6. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  7. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  8. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  9. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  10. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

随机推荐