File: 51-join-defunct-thread.lua

package info (click to toggle)
lua-cqueues 20200726-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 1,848 kB
  • sloc: ansic: 23,623; sh: 2,984; makefile: 24
file content (76 lines) | stat: -rwxr-xr-x 2,062 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#!/bin/sh
_=[[
	. "${0%%/*}/regress.sh"
	exec runlua -t -j- "$0" "$@"
]]

require"regress".export".*"

check(jit, "LuaJIT required")
check(errno.EOWNERDEAD, "EOWNERDEAD not defined")

local thr, con = assert(thread.start(function (con)
	local errno = require"cqueues.errno"
	local ffi  = require"ffi"

	require"regress".export".*"

	--
	-- NOTE: On musl-libc the parent process deadlocks on flockfile as
	-- apparently the thread dies when writing to stderr. Log to our
	-- communications socket instead, which doesn't hold any locks.
	--
	local function info(...)
		con:write(string.format(...), "\n")
		con:flush()
	end

	info"calling prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT)"

	local PR_SET_SECCOMP = 22
	local SECCOMP_MODE_STRICT = 1
	ffi.cdef"int prctl(int, unsigned long, unsigned long, unsigned long, unsigned long)"
	local ok, rv = pcall(function () return ffi.C.prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, 0, 0, 0) end)

	if not ok then
		local rv = string.match(rv, "[^:]+:[^:]+$") or rv
		info("prctl call failed: %s", rv)
	elseif rv ~= 0 then
		info("prctl call failed: %s", errno.strerror(ffi.errno()))
	else
		info"attempting to open /nonexistant"
		io.open"/nonexistant" -- should cause us to be killed
		info"prctl call failed: still able to open files"
	end

	info"calling pthread_exit"

	ffi.cdef"void pthread_exit(void *);"
	ffi.C.pthread_exit(nil)

	info"pthread_exit call failed: thread still running"
end))

local main = check(cqueues.new())

-- read thread's log lines from pcall because socket:read will throw an
-- error when the socket is closed asynchronously below.
check(main:wrap(pcall, function ()
	for ln in con:lines() do
		info("%s", ln)
	end
end))

check(main:wrap(function ()
	local ok, why, code = auxlib.fileresult(thr:join(5))

	check(not ok, "thread unexpectedly joined (%s)", why or "no error")
	check(code == errno.EOWNERDEAD or code == errno.ETIMEDOUT, "unexpected error: %s", why)
	check(code == errno.EOWNERDEAD, "robust mutex strategy not supported on this system")

	con:close()
end))

check(main:loop())

say"OK"