Skip to content

Commit 4aecd8e

Browse files
Oleg Chaplashkinylobankov
authored andcommitted
Fix detect tarantool crash at exit
> What's the problem? During the shutdown of the server, the server process is polled. If the call `ffi.C.kill(<pid>, 0)` returns the value 0, then the process will be considered alive, otherwise it will be dead. Luatest cannot distinguish the states when the process is completed correctly and incorrectly. This means that if a critical error appears at the end of the process (e.g., segmentation fault), then stopping the server will be considered successful (and the test-case too). > What's the solution? Each process contains its own instance of output_beautifier (which reads stdout and stderr). Now this instance will contain the stderr field (str) where the entire stderr from the process will be saved. During the server shutdown, it looks for the substring 'segmentation fault' and return an error if the substring is found: Segmentation fault during process termination (alias: master, workdir: master-SrQjEIiLyRHS, pid: 152323) Segmentation fault code: SEGV_MAPERR addr: (nil) ... Closes #252
1 parent 89da427 commit 4aecd8e

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

luatest/output_beautifier.lua

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ function OutputBeautifier.mt:initialize()
7070
self.class.COLOR_BY_NAME[self.color] or
7171
OutputBeautifier:next_color_code()
7272
self.pipes = {stdout = ffi_io.create_pipe(), stderr = ffi_io.create_pipe()}
73+
self.stderr = ''
7374
end
7475

7576
-- Replace standard output descriptors with pipes.
@@ -86,7 +87,7 @@ function OutputBeautifier.mt:enable(options)
8687
end
8788
self.fibers = {}
8889
for i, pipe in pairs(self.pipes) do
89-
self.fibers[i] = fiber.new(self.run, self, pipe[0])
90+
self.fibers[i] = fiber.new(self.run, self, pipe[0], i)
9091
end
9192
self.fibers.pid_tracker = options and options.track_pid and fiber.new(function()
9293
Process = Process or require('luatest.process')
@@ -138,12 +139,16 @@ end
138139
--
139140
-- Every line with log level mark (` X> `) changes the color for all the following
140141
-- lines until the next one with the mark.
141-
function OutputBeautifier.mt:run(fd)
142+
function OutputBeautifier.mt:run(fd, pipe)
142143
local prefix = self.color_code .. self.prefix .. ' | '
143144
local line_color_code = self.class.RESET_TERM
144145
while fiber.testcancel() or true do
145146
self:process_fd_output(fd, function(chunks)
146-
local lines = table.concat(chunks):split('\n')
147+
local raw_lines = table.concat(chunks)
148+
if pipe == 'stderr' then
149+
self.stderr = self.stderr .. raw_lines
150+
end
151+
local lines = raw_lines:split('\n')
147152
if lines[#lines] == '' then
148153
table.remove(lines)
149154
end

luatest/server.lua

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,17 @@ function Server:stop()
367367
if not ok and not err:find('Process is terminated when waiting for') then
368368
error(err)
369369
end
370+
if self.process.output_beautifier.stderr:find('Segmentation fault') then
371+
error(
372+
('Segmentation fault during process termination (alias: %s, workdir: %s, pid: %d)\n%s')
373+
:format(
374+
self.alias,
375+
fio.basename(self.workdir),
376+
self.process.pid,
377+
self.process.output_beautifier.stderr
378+
)
379+
)
380+
end
370381
log.debug('Killed server process PID ' .. self.process.pid)
371382
self.process = nil
372383
end

0 commit comments

Comments
 (0)