[проверить все нити следов, чтобы найти виновника]
Даже полностью расширенный стек вызовов все еще может скрывать от вас актуальную строку кода, когда вы используете более одного потока!
Пример: один поток выполняет итерации ruby Hash, другой поток пытается его изменить. БУМ! Исключение! И проблема с трассировкой стека, которую вы получаете при попытке изменить хэш «занят», состоит в том, что она показывает цепочку функций вплоть до того места, где вы пытаетесь изменить хэш, но она НЕ показывает, кто в настоящее время выполняет ее параллельно ( кому это принадлежит)! Вот способ выяснить это путем печати трассировки стека для ВСЕХ запущенных в данный момент потоков. Вот как это сделать:
# This solution was found in comment by @thedarkone on https://github.com/rails/rails/issues/24627
rescue Object => boom
thread_count = 0
Thread.list.each do |t|
thread_count += 1
err_msg += "--- thread #{thread_count} of total #{Thread.list.size} #{t.object_id} backtrace begin \n"
# Lets see if we are able to pin down the culprit
# by collecting backtrace for all existing threads:
err_msg += t.backtrace.join("\n")
err_msg += "\n---thread #{thread_count} of total #{Thread.list.size} #{t.object_id} backtrace end \n"
end
# and just print it somewhere you like:
$stderr.puts(err_msg)
raise # always reraise
end
Приведенный выше фрагмент кода полезен даже для образовательных целей, поскольку он может показать вам (например, рентген), сколько потоков у вас на самом деле (по сравнению с тем, сколько вы думаете, у вас есть - довольно часто эти два числа разные;) 1009 *