mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
SIGINFO prints thread backtraces (#1320)
This commit is contained in:
parent
3ce98b7960
commit
e96e798068
7 changed files with 62 additions and 10 deletions
|
@ -346,8 +346,8 @@ module Puma
|
|||
log "+ Changing to #{dir}"
|
||||
Dir.chdir dir
|
||||
end
|
||||
|
||||
# Inside of a child process, this will return all zeroes, as @workers is only populated in
|
||||
|
||||
# Inside of a child process, this will return all zeroes, as @workers is only populated in
|
||||
# the master process.
|
||||
def stats
|
||||
old_worker_count = @workers.count { |w| w.phase != @phase }
|
||||
|
|
|
@ -325,6 +325,17 @@ module Puma
|
|||
log "- Goodbye!"
|
||||
end
|
||||
|
||||
def log_thread_status
|
||||
Thread.list.each do |thread|
|
||||
@events.log "Thread TID-#{thread.object_id.to_s(36)} #{thread['label']}"
|
||||
if thread.backtrace
|
||||
@events.log thread.backtrace.join("\n")
|
||||
else
|
||||
@events.log "<no backtrace available>"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def set_process_title
|
||||
Process.respond_to?(:setproctitle) ? Process.setproctitle(title) : $0 = title
|
||||
end
|
||||
|
@ -441,6 +452,15 @@ module Puma
|
|||
rescue Exception
|
||||
log "*** SIGHUP not implemented, signal based logs reopening unavailable!"
|
||||
end
|
||||
|
||||
begin
|
||||
Signal.trap "SIGINFO" do
|
||||
log_thread_status
|
||||
end
|
||||
rescue Exception
|
||||
# Not going to log this one, as SIGINFO is *BSD only and would be pretty annoying
|
||||
# to see this constantly on Linux.
|
||||
end
|
||||
end
|
||||
|
||||
def require_rubygems_min_version!(min_version, feature)
|
||||
|
|
|
@ -97,7 +97,7 @@ class TestIntegration < Minitest::Test
|
|||
end
|
||||
|
||||
# gets worker pids from @server output
|
||||
def get_worker_pids(phase, size = WORKERS)
|
||||
def get_worker_pids(phase = 0, size = WORKERS)
|
||||
pids = []
|
||||
re = /pid: (\d+)\) booted, phase: #{phase}/
|
||||
while pids.size < size
|
||||
|
|
|
@ -8,6 +8,20 @@ class TestIntegrationCluster < TestIntegration
|
|||
super
|
||||
end
|
||||
|
||||
def test_siginfo_thread_print
|
||||
skip_unless_signal_exist? :INFO
|
||||
|
||||
cli_server("-w #{WORKERS} -q test/rackup/hello.ru")
|
||||
worker_pids = get_worker_pids
|
||||
output = []
|
||||
t = Thread.new { output << @server.readlines }
|
||||
Process.kill(:INFO, worker_pids.first)
|
||||
Process.kill(:INT, @server.pid)
|
||||
t.join
|
||||
|
||||
assert_match "Thread TID", output.join
|
||||
end
|
||||
|
||||
def test_usr2_restart
|
||||
_, new_reply = restart_server_and_listen("-q -w #{WORKERS} test/rackup/hello.ru")
|
||||
assert_equal "Hello World", new_reply
|
||||
|
@ -92,7 +106,7 @@ class TestIntegrationCluster < TestIntegration
|
|||
pid = cli_server("-w #{WORKERS} test/rackup/hello.ru").pid
|
||||
|
||||
# Get the PIDs of the child workers.
|
||||
worker_pids = get_worker_pids 0
|
||||
worker_pids = get_worker_pids
|
||||
|
||||
# Signal the workers to terminate, and wait for them to die.
|
||||
Process.kill :TERM, pid
|
||||
|
|
|
@ -84,4 +84,17 @@ class TestIntegrationSingle < TestIntegration
|
|||
|
||||
assert_raises(Errno::ECONNREFUSED) { TCPSocket.new(HOST, @tcp_port) }
|
||||
end
|
||||
|
||||
def test_siginfo_thread_print
|
||||
skip_unless_signal_exist? :INFO
|
||||
|
||||
cli_server("test/rackup/hello.ru")
|
||||
output = []
|
||||
t = Thread.new { output << @server.readlines }
|
||||
Process.kill(:INFO, @server.pid)
|
||||
Process.kill(:INT, @server.pid)
|
||||
t.join
|
||||
|
||||
assert_match "Thread TID", output.join
|
||||
end
|
||||
end
|
||||
|
|
|
@ -60,4 +60,14 @@ class TestLauncher < Minitest::Test
|
|||
# assert no "/../" in path
|
||||
refute_match(%r{/\.\./}, puma_wild_location)
|
||||
end
|
||||
|
||||
def test_prints_thread_traces
|
||||
events = Puma::Events.strings
|
||||
l = Puma::Launcher.new(Puma::Configuration.new, events: events)
|
||||
|
||||
l.send(:log_thread_status)
|
||||
events.stdout.rewind
|
||||
|
||||
assert_match "Thread TID", events.stdout.read
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ class TestPumaServer < Minitest::Test
|
|||
|
||||
@app = lambda { |env| [200, {}, [env['rack.url_scheme']]] }
|
||||
|
||||
@events = Puma::Events.new STDOUT, STDERR
|
||||
@events = Puma::Events.strings
|
||||
@server = Puma::Server.new @app, @events
|
||||
end
|
||||
|
||||
|
@ -280,9 +280,6 @@ EOF
|
|||
end
|
||||
|
||||
def test_doesnt_print_backtrace_in_production
|
||||
@events = Puma::Events.strings
|
||||
@server = Puma::Server.new @app, @events
|
||||
|
||||
@server.app = proc { |e| raise "don't leak me bro" }
|
||||
@server.leak_stack_on_error = false
|
||||
@server.add_tcp_listener @host, @port
|
||||
|
@ -298,7 +295,6 @@ EOF
|
|||
end
|
||||
|
||||
def test_prints_custom_error
|
||||
@events = Puma::Events.strings
|
||||
re = lambda { |err| [302, {'Content-Type' => 'text', 'Location' => 'foo.html'}, ['302 found']] }
|
||||
@server = Puma::Server.new @app, @events, {:lowlevel_error_handler => re}
|
||||
|
||||
|
@ -314,7 +310,6 @@ EOF
|
|||
end
|
||||
|
||||
def test_leh_gets_env_as_well
|
||||
@events = Puma::Events.strings
|
||||
re = lambda { |err,env|
|
||||
env['REQUEST_PATH'] || raise("where is env?")
|
||||
[302, {'Content-Type' => 'text', 'Location' => 'foo.html'}, ['302 found']]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue