From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp43.i.mail.ru (smtp43.i.mail.ru [94.100.177.103]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id EDB22430407 for ; Wed, 19 Aug 2020 20:23:26 +0300 (MSK) From: Ilya Kosarev Date: Wed, 19 Aug 2020 20:23:24 +0300 Message-Id: <20200819172324.6188-1-i.kosarev@tarantool.org> Subject: [Tarantool-patches] [PATCH] test: concurrent tuple update segfault on bitset index iteration List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: alyapunov@tarantool.org Cc: tarantool-patches@dev.tarantool.org Concurrent tuple update could segfault on BITSET_ALL_NOT_SET iterator usage. Fixed in 850054b2dbca257076c3f7c22e00564ac55b70d5. Closes #1088 --- Branch: https://github.com/tarantool/tarantool/tree/i.kosarev/gh-1088-concurrent-tuple-update-segfault-with-bitset-index Issue: https://github.com/tarantool/tarantool/issues/1088 test/box/bitset.result | 86 ++++++++++++++++++++++++++++++++++++++++ test/box/bitset.test.lua | 42 ++++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/test/box/bitset.result b/test/box/bitset.result index bf44773ef3..5da068385c 100644 --- a/test/box/bitset.result +++ b/test/box/bitset.result @@ -2020,3 +2020,89 @@ s:drop() box.schema.func.drop('s') --- ... +-- gh-1088 concurrent tuple update segfaults on BITSET_ALL_NOT_SET iteration +test_run = require('test_run').new() +--- +... +fiber = require('fiber') +--- +... +s = box.schema.space.create('gh-1088') +--- +... +_ = s:create_index('primary', {type = 'hash', parts = {1, 'num'}}) +--- +... +_ = s:create_index('bitset', {unique = false, type = 'BITSET', parts = {2, 'num'}}) +--- +... +for i = 1, 100 do s:insert{i, 0, i - 1} end +--- +... +counter = 0 +--- +... +test_run:cmd("setopt delimiter ';'") +--- +- true +... +function update() + for _, t in s.index.bitset:pairs(1, {iterator = box.index.BITS_ALL_NOT_SET}) do + counter = counter + 1 + s:update(t[1], {{'+', 3, 11}}) + fiber.sleep(0) + end + fiber.self():cancel() +end; +--- +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... +fibers = {} +--- +... +for _ = 1, 100 do table.insert(fibers, fiber.create(update)) end +--- +... +updating = true +--- +... +test_run:cmd("setopt delimiter ';'") +--- +- true +... +while updating do + updating = false + for _, f in pairs(fibers) do + if f:status() ~= 'dead' then updating = true end + end + fiber.sleep(0.001) +end; +--- +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... +s:get(1) +--- +- [1, 0, 1100] +... +s:get(2) +--- +- [2, 0, 1101] +... +s:get(3) +--- +- [3, 0, 1102] +... +s:get(4) +--- +- [4, 0, 1103] +... +counter -- total updates counter +--- +- 10000 +... diff --git a/test/box/bitset.test.lua b/test/box/bitset.test.lua index d644d34e0b..dd432edeb0 100644 --- a/test/box/bitset.test.lua +++ b/test/box/bitset.test.lua @@ -162,3 +162,45 @@ _ = s:create_index('pk') _ = s:create_index('idx', {type = 'bitset', func = box.func.s.id, parts = {{1, 'unsigned'}}}) s:drop() box.schema.func.drop('s') + +-- gh-1088 concurrent tuple update segfaults on BITSET_ALL_NOT_SET iteration +test_run = require('test_run').new() +fiber = require('fiber') + +s = box.schema.space.create('gh-1088') +_ = s:create_index('primary', {type = 'hash', parts = {1, 'num'}}) +_ = s:create_index('bitset', {unique = false, type = 'BITSET', parts = {2, 'num'}}) +for i = 1, 100 do s:insert{i, 0, i - 1} end + +counter = 0 +test_run:cmd("setopt delimiter ';'") +function update() + for _, t in s.index.bitset:pairs(1, {iterator = box.index.BITS_ALL_NOT_SET}) do + counter = counter + 1 + s:update(t[1], {{'+', 3, 11}}) + fiber.sleep(0) + end + fiber.self():cancel() +end; +test_run:cmd("setopt delimiter ''"); + +fibers = {} +for _ = 1, 100 do table.insert(fibers, fiber.create(update)) end + +updating = true +test_run:cmd("setopt delimiter ';'") +while updating do + updating = false + for _, f in pairs(fibers) do + if f:status() ~= 'dead' then updating = true end + end + fiber.sleep(0.001) +end; +test_run:cmd("setopt delimiter ''"); + +s:get(1) +s:get(2) +s:get(3) +s:get(4) + +counter -- total updates counter -- 2.17.1