如何调试以找到阻塞主线程的代码

how to debug to find the code that is blocking the main thread

我有一个 Rails 应用 运行ning 版本 6.1.1,目前我们使用 Ruby 2.7.2

在尝试升级到 Ruby 3 时,我遇到了一个有趣的问题:某些代码显然正在阻塞主线程。当我尝试启动服务器或 运行 测试时,控制台卡住了,我什至无法停止进程,我必须 kill 它。

我追踪到一个名为 valvat 的 gem,用于验证欧盟增值税号。我在它的 Github 回购上打开了一个问题,但维护者即使使用我拥有的 Gemfile.lock 也无法重现,这让我相信它可能不仅仅是 gem,必须成为我的代码中的其他东西。

这是我尝试启动服务器时发生的情况:

=> Booting Puma
=> Rails 6.1.1 application starting in development
=> Run `bin/rails server --help` for more startup options
^C^C^C

如你所见,我什至无法阻止它,线程现在已挂起,我无法确切地告诉谁。

我尝试 运行 -b -w 的规范以查看我能看到什么,但得到了同样的错误:线程挂起,我从 Ruby 得到的警告只是通用的像 method already defined 之类的。

这是控制台的最后输出,同时 运行在线程挂起之前使用 -b -w 指定规格:

/Users/luiz/rails_dev/app/config/initializers/logging_rails.rb:18: warning: method redefined; discarding old tag_logger
/Users/luiz/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/activejob-6.1.1/lib/active_job/logging.rb:19: warning: previous definition of tag_logger was here

事情是,当我通过规范 运行 删除 gem 和 运行 这个命令时,我也收到了这些警告,然后没有问题。

有没有办法追踪到导致线程挂起的原因?

如果没有错误消息,则很难理解应用程序挂起的确切位置。

由于开发人员无法使用您的 Gemfile.lock 重现,您的配置文件或初始化程序之一可能是罪魁祸首。您可以使用相同的 Gemfile 创建一个新的空白应用程序,一个一个地添加您的配置文件和初始化程序文件,并每次测试服务器是否运行,直到您找到导致冻结的原因。

也用另一个 Ruby 版本测试您的应用程序(您使用的是 rbenv 还是 RVM?)

同时检查您的系统日志,因为 valvat 调用 Web 服务,您可能会在那里发现连接错误。查看此文档以了解如何访问您的系统日志:https://www.howtogeek.com/356942/how-to-view-the-system-log-on-a-mac/