Skip to content

Segfault if used with tarantool debug build #59

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
LeonidVas opened this issue Jun 1, 2020 · 13 comments · Fixed by #60 or #111
Closed

Segfault if used with tarantool debug build #59

LeonidVas opened this issue Jun 1, 2020 · 13 comments · Fixed by #60 or #111
Assignees
Labels
bug Something isn't working

Comments

@LeonidVas
Copy link
Collaborator

LeonidVas commented Jun 1, 2020

Got segfault on both master and this patchset (#54) on tarantool 2.5.0-62-gbb7c3d167 (debug) when run tests (cd test && ./test-run.py).

#0  0x00007f3f837665f1 in raise () from /lib64/libc.so.6
#1  0x00007f3f8375053b in abort () from /lib64/libc.so.6
#2  0x000056508e4b15b7 in sig_fatal_cb (signo=11, siginfo=0x7f3f6cb7f3f0, context=0x7f3f6cb7f2c0) at /usr/src/debug/dev-db/tarantool-9999/tarantool-9999/src/main.cc:301
#3  <signal handler called>
#4  0x00007f3f84767eab in slab_from_ptr (ptr=0x7f3f810300a0, slab_mask=0) at /home/alex/p/tarantool-meta/memcached/third_party/small/small/slab_cache.h:203
#5  0x00007f3f847680ce in mempool_free (pool=0x56508feebb50, ptr=0x7f3f810300a0) at /home/alex/p/tarantool-meta/memcached/third_party/small/small/mempool.h:274
#6  0x00007f3f84768416 in iobuf_delete (ibuf=0x7f3f810300a0, obuf=0x7f3f81040480) at /home/alex/p/tarantool-meta/memcached/memcached/internal/network.c:69
#7  0x00007f3f8476acf8 in memcached_handler (p=0x56508feec040, fd=22) at /home/alex/p/tarantool-meta/memcached/memcached/internal/memcached.c:258
#8  0x000056508e675c6b in lj_vm_ffi_call () at buildvm_x86.dasc:2578
#9  0x000056508e69bfe9 in lj_ccall_func (L=L@entry=0x4149e370, cd=<optimized out>) at lj_ccall.c:1150
#10 0x000056508e6716c8 in lj_cf_ffi_meta___call (L=0x4149e370) at lib_ffi.c:230
#11 0x000056508e673cbb in lj_BC_FUNCC () at buildvm_x86.dasc:809
#12 0x000056508e650a56 in lua_pcall (L=0x4149e370, nargs=<optimized out>, nresults=-1, errfunc=<optimized out>) at lj_api.c:1158
#13 0x000056508e5e4822 in luaT_call (L=0x4149e370, nargs=3, nreturns=-1) at /usr/src/debug/dev-db/tarantool-9999/tarantool-9999/src/lua/utils.c:1053
#14 0x000056508e5dd150 in lua_fiber_run_f (ap=0x7f3f81001470) at /usr/src/debug/dev-db/tarantool-9999/tarantool-9999/src/lua/fiber.c:443
#15 0x000056508e4b0e69 in fiber_cxx_invoke(fiber_func, typedef __va_list_tag __va_list_tag *) (f=0x56508e5dd0dc <lua_fiber_run_f>, ap=0x7f3f81001470)
    at /usr/src/debug/dev-db/tarantool-9999/tarantool-9999/src/lib/core/fiber.h:782
#16 0x000056508e606a71 in fiber_loop (data=0x0) at /usr/src/debug/dev-db/tarantool-9999/tarantool-9999/src/lib/core/fiber.c:869
#17 0x000056508e7493b4 in coro_init () at /usr/src/debug/dev-db/tarantool-9999/tarantool-9999/third_party/coro/coro.c:110

#54 (comment)

@LeonidVas LeonidVas self-assigned this Jun 1, 2020
@LeonidVas LeonidVas added blocking bug Something isn't working labels Jun 1, 2020
@LeonidVas
Copy link
Collaborator Author

After a brief research of the bug, it seems that the problem is in different versions of the “small” library used in the tarantool and memcached module.
The proofs:

  • If the "small" will be checkout to the same commit as in tarantool, the problem will disappear.
  • if tarantool will be checkout to tarantool/tarantool@2c27c24, the problem will disappear.

@LeonidVas
Copy link
Collaborator Author

As I understood the problem is this:
Tarantool is export the next symbols:

└──╼ nm -gD ./src/tarantool | grep mempool
00000000007cc1a1 T mempool_alloc
00000000007cbfac T mempool_create_with_order
00000000007cc115 T mempool_destroy
00000000007d1000 T mempool_iterator_create
00000000007d104b T mempool_iterator_next
00000000007cc34d T mempool_stats

Memcached uses the next functions:
mempool_create (defined in small/small/mempool.h) which uses mempool_create_with_order()
mempool_free((defined in small/small/mempool.h)
After tarantool/small@0ce1268 the size of the struct mempool has been changed (was changed the size of mslab_tree_t).

The reason of the bug is the next: when initializing a struct mempool in mempool_create(memcached version) mempool_create_with_order is called(tarantool version with other struct mempool size), where some fields of the struct mempool are assigned. After that, the corrupted struct mempool will be used in mempool_free(memcached version). And, "BAM!", segfault when trying to use a NULL pointer.

@LeonidVas
Copy link
Collaborator Author

LeonidVas commented Jun 1, 2020

Hot fix:
It seems that an updating the version of the "small" library will fix memcached for tarantool> = 1.10 .

@Totktonada
Copy link
Member

I vote to workaround this for now for tarantool >= 1.10 and leave the issue open to investigate further.

LeonidVas added a commit that referenced this issue Jun 2, 2020
The "small" library version has been updated.

Part of #59
@LeonidVas LeonidVas linked a pull request Jun 2, 2020 that will close this issue
LeonidVas added a commit that referenced this issue Jun 2, 2020
Crutch. If SMALL_EMBEDDED is used, "small" will try to compile
with the default flags, but it can't be compiled with std=c89.
Look like a "small" library bug.

Part of #59
@Totktonada
Copy link
Member

NB: Would some ABI compliance checker (say, this) help us with detecting ABI incompatibility in small?

@LeonidVas
Copy link
Collaborator Author

NB: Would some ABI compliance checker (say, this) help us with detecting ABI incompatibility in small?

If I understand correctly it's not solve the problem, because now we have a situation when the memcached version implicitly depends on the tarantool "small" version. And now it should be synchronously update or rollback.

LeonidVas added a commit that referenced this issue Jun 3, 2020
The main reason of update:
When the memcached module is linked with tarantool,
it uses some of the "small" functions from tarantool
(which were exported by tarantool, for example:
mempool_create_with_order()) and some from the "small"
with wich it was built (for example: mempool_create(),
mempool_free()). This can lead to undefined behavior
(segfault for example). To avoid the problem, will use
the same (close) version of the "small" as tarantool.

Part of #59
LeonidVas added a commit that referenced this issue Jun 3, 2020
If SMALL_EMBEDDED is used, "small" will try to compile
with the default flags, but it can't be compiled with std=c89.
Look like a "small" library bug.
So, we will use std=c99 globally as workaround.

Part of #59
Totktonada pushed a commit that referenced this issue Jun 3, 2020
If SMALL_EMBEDDED is used, "small" will try to compile
with the default flags, but it can't be compiled with std=c89.
Look like a "small" library bug.
So, we will use std=c99 globally as workaround.

See tarantool/small#25

Part of #59

@Totktonada: added the comment.
Totktonada pushed a commit that referenced this issue Jun 3, 2020
The main reason of update:
When the memcached module is linked with tarantool,
it uses some of the "small" functions from tarantool
(which were exported by tarantool, for example:
mempool_create_with_order()) and some from the "small"
with wich it was built (for example: mempool_create(),
mempool_free()). This can lead to undefined behavior
(segfault for example). To avoid the problem, will use
the same (close) version of the "small" as tarantool.

Part of #59
Totktonada pushed a commit that referenced this issue Jun 3, 2020
If SMALL_EMBEDDED is used, "small" will try to compile
with the default flags, but it can't be compiled with std=c89.
Look like a "small" library bug.
So, we will use std=c99 globally as workaround.

See tarantool/small#25

Part of #59

@Totktonada: added the comment.
@Totktonada
Copy link
Member

Worked around in PR #60.

@Totktonada
Copy link
Member

But a proper fix should be implemented in a long term.

@Totktonada Totktonada reopened this Jun 3, 2020
@Totktonada
Copy link
Member

Curious fact: everything works until 2.5.0-42-g03790ac55 ('cmake: remove dynamic-list linker option'), which is fix of #2971 ('Unhide back all symbols in 1.7+'). (I verified it.)

@LeonidVas
Copy link
Collaborator Author

Curious fact: everything works until 2.5.0-42-g03790ac55 ('cmake: remove dynamic-list linker option'), which is fix of #2971 ('Unhide back all symbols in 1.7+'). (I verified it.)

Yep. If tarantool will hides symbols, the problem go away). Memcached will use only its own version of small.

@Totktonada
Copy link
Member

Totktonada commented Mar 28, 2022

Background information

We're going to decouple tarantool's runtime arena and a slab cache upward the
arena from memcached's arena and slab cache, because tarantool's small version
was updated in 2.10.0-beta1-315-g173ce9fbb ('small: fix incorrect mempool
group creation'). It will be done in the scope of #96.

And now I want to return here to make sure that all problems around
small-in-the-module and small-in-tarantool are resolved.

The key fact here is that we have certain range of tarantool versions, where
symbols are open. Everything aside this range should be okay (after #96 fix).
We should answer to the question: whether we can hold a particular small
version in memcached and be sure that the symbols clash does not break
anything.

Symbols was visible by default since 2.5.0-42-g03790ac55 ('cmake: remove
dynamic-list linker option') till 2.9.0-244-g5ceabb378 ('cmake: hide tarantool
symbols back'). It corresponds to the following releases:

  • 2.5.1, 2.5.2, 2.5.3
  • 2.6.1, 2.6.2, 2.6.3
  • 2.7.1, 2.7.2, 2.7.3
  • 2.8.1, 2.8.2, 2.8.3 (maybe future 2.8.*, if we'll release them)

memcached's small version is 1.1-63-g3df5050.

Tarantool's small versions:

Tarantool Small
2.5.1 1.1-71-gfcac155
2.5.2 1.1-71-gfcac155
2.5.3 1.1-77-g3ae6cbb
2.6.1 1.1-71-gfcac155
2.6.2 1.1-77-g3ae6cbb
2.6.3 1.1-81-g279fa38
2.7.1 1.1-77-g3ae6cbb
2.7.2 1.1-81-g279fa38
2.7.3 1.1-82-g781fd38
2.8.1 1.1-81-g279fa38
2.8.2 1.1-82-g781fd38
2.8.3 1.1-82-g781fd38
2.8.3-63-gb96997083 1.1-82-g781fd38

Note: small was bumped in 2.5.0-42-g03790ac55 by a mistake and reverted back
in 2.5.0-43-g61d2cb64f.

Analysis

Here I want to do an attepmt to estimate small's changes in terms of ABI
compatibility. The comments for commits below attempt to answer the question:
why it cannot affect the memcached module work.

  • 1.1-63-g3df5050.

    Base version (used by memcached).

  • 1.1-64-g0e4fd61 ('rlist: use built-in offsetof() when
    possible')

    Should not actually change a behaviour, but rather eliminate a clang
    warning.

  • 1.1-65-g79c7b08 ('travis-ci: update the list of supported
    distributions')

    CI update.

  • 1.1-66-g5706060 ('travis-ci: push to 2.3 and 2.4
    repositories')

    CI update.

  • 1.1-67-gcd7c005 ('lsregion: fix slab_unmap() called on
    malloced slab')

    We don't use lsregion in the module.

  • 1.1-68-gd9f8079 ('lsregion: introduce aligned alloc')

    It is again about lsregion, so irrelevant for us.

  • 1.1-69-g7546462 ('region: new region_alloc_array, updated
    alloc_object')

    It is about region_alloc_object() and region_alloc_array() macros,
    irrelevant for us.

  • 1.1-70-g34eb29d ('test: update lsregion .result file')

    It only updates a test.

  • 1.1-71-gfcac155 ('test: don't use not aligned size for
    mempool')

    It only updates a test.

    Not relevant here, but there is an interesting note in the commit message:

    Mempool expects aligned object size.

    Hm. If it the general rule, then it should be either adjusted or asserted in
    mempool_create(). If not, it is not clear, when it is applicable and when
    not. And what are consequences on x86_64 if we violate this rule.

    Maybe it was so till 1.1-79-g799f109 (see mempool.c changes) and is not
    actual for recent small?

  • 1.1-72-g8167b86 ('Fix Centos6 build failed')

    RPM spec update.

  • 1.1-73-g9ee874c ('Fix build error')

    It fixes a build fail (of a test) that was introduced in 1.1-71-gfcac155.

  • 1.1-74-g2e90bcc ('Remove Ubuntu 19.04 Disco')

    CI update.

  • 1.1-75-g6c8846c ('small: implement new size class
    evaluation')

    It is append-only change. Should be okay.

  • 1.1-76-g59b5ccc ('test: add small allocator performance
    test')

    Only adds a test.

  • 1.1-77-g3ae6cbb ('small: changed small allocator pool
    management')

    All changes are about small_alloc(). We don't use it in the module.

  • 1.1-78-g29bf0cb ('replace strong cas with weak version
    inside loops')

    Calling of module's small function or tarantool's one has exactly same
    effect. It should be safe.

  • 1.1-79-g799f109 ('small: add granularity option to
    small_alloc_create')

    Regarding mempool.c changes: those definitely will not make things worse.

    Regarding small_alloc() changes: it is irrelevant for us, because it is
    not used in the module.

  • 1.1-80-g2ab83e1 ('test: fix error in flaky test')

    Test fix.

  • 1.1-81-g279fa38 ('test: obuf test refactoring')

    Test change.

  • 1.1-82-g781fd38 ('build: fix tarantool build failure on
    xcode 12.5')

    It only changes include files placement. No ABI changes.

So the changes look safe in terms of ABI compatibility (taking into account the
fact that we use only mempool, region, ibuf and obuf in the module).

Experiment

Build Tarantool in Debug configuration:

$ git clean -xffd; git submodule foreach --recursive 'git clean -xffd'
$ git checkout -- .
$ git checkout $TAG
$ rm -r third_party test-run
$ git checkout -- third_party
$ git submodule update --init --recursive
$ <..apply tweaks (see below)..>
$ cmake . -DCMAKE_BUILD_TYPE=Debug -DENABLE_BACKTRACE=ON -DENABLE_DIST=ON -DENABLE_FEEDBACK_DAEMON=OFF -DENABLE_BUNDLED_LIBCURL=OFF && make -j
$ make DESTDIR=../$(git describe) install

Build Tarantool in RelWithDebInfo configuration:

<..same as above..>
$ cmake . -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_BACKTRACE=ON -DENABLE_DIST=ON -DENABLE_FEEDBACK_DAEMON=OFF -DENABLE_BUNDLED_LIBCURL=OFF && make -j
$ make DESTDIR=../$(git describe)-release install
Build tweaks
  • 2.5.1

    $ git show 2.6.0-130-g0ffba1972 test/unit/guava.c | patch -p1
    $ git show 2.10.0-beta1-377-g9c01b325a test/unit/guard.cc | sed s/xmalloc/malloc/ | patch -p1
  • 2.5.2, 2.5.3, 2.6.*, 2.7.*, 2.8.1, 2.8.2

    $ git show 2.10.0-beta1-377-g9c01b325a test/unit/guard.cc | sed s/xmalloc/malloc/ | patch -p1

Build memcached in Debug configuration:

$ cmake . -DCMAKE_BUILD_TYPE=Debug && make
<..ensure that the following line is present..>
-- Could NOT find Small (missing: SMALL_INCLUDE_DIR SMALL_LIBRARY)
<...>

Build memcached in RelWithDebInfo configuration:

$ cmake . -DCMAKE_BUILD_TYPE=RelWithDebInfo && make
<..ensure that the following line is present..>
-- Could NOT find Small (missing: SMALL_INCLUDE_DIR SMALL_LIBRARY)
<...>

Run memcached tests (against Debug tarantool):

$ (export PATH="$(realpath ../${TAG}/usr/local/bin):${PATH}"; make test-memcached && make test-memcached-bench)
# or for all tarantool builds at once
$ for TAG in 2.5.{1..3} 2.6.{1..3} 2.7.{1..3} 2.8.{1..3} 2.8.3-63-gb96997083; do (export PATH="$(realpath ../${TAG}/usr/local/bin):${PATH}"; make test-memcached && make test-memcached-bench); done

Run memcached tests (against RelWithDebInfo tarantool):

$ (export PATH="$(realpath ../${TAG}-release/usr/local/bin):${PATH}"; make test-memcached && make test-memcached-bench)
# or for all tarantool builds at once
$ for TAG in 2.5.{1..3} 2.6.{1..3} 2.7.{1..3} 2.8.{1..3} 2.8.3-63-gb96997083; do (export PATH="$(realpath ../${TAG}-release/usr/local/bin):${PATH}"; make test-memcached && make test-memcached-bench); done

Note: I have problems with libmemcached build on Gentoo (it seems, it requires
an update from upstream), so I didn't run make test-memcached-capable.

memcached master: 1.0.1-40-g5aaac83.
memcached PR #102: commit aa1f6e2.

Tarantool Debug + memcached Debug:

Tarantool memcached master memcached master + tests from PR #102 memcached PR #102
2.5.1 OK OK OK
2.5.2 OK OK OK
2.5.3 OK OK OK
2.6.1 OK OK OK
2.6.2 OK OK OK
2.6.3 OK OK OK
2.7.1 OK OK OK
2.7.2 OK OK OK
2.7.3 OK OK OK
2.8.1 OK OK OK
2.8.2 OK1 OK OK
2.8.3 OK OK OK
2.8.3-63-gb96997083 OK OK OK

Tarantool Debug + memcached RelWithDebInfo:

Tarantool memcached master memcached master + tests from PR #102 memcached PR #102
2.5.1 OK OK OK
2.5.2 OK OK OK
2.5.3 OK OK OK
2.6.1 OK OK OK
2.6.2 OK OK OK
2.6.3 OK OK OK
2.7.1 OK OK OK
2.7.2 OK OK OK
2.7.3 OK OK OK
2.8.1 OK OK OK
2.8.2 OK OK OK
2.8.3 OK OK OK
2.8.3-63-gb96997083 OK OK OK

Tarantool RelWithDebInfo + memcached Debug:

Tarantool memcached master memcached master + tests from PR #102 memcached PR #102
2.5.1 OK OK OK
2.5.2 OK OK OK
2.5.3 OK OK OK
2.6.1 OK OK OK
2.6.2 OK OK OK
2.6.3 OK OK OK
2.7.1 OK OK OK
2.7.2 OK OK OK
2.7.3 OK OK OK
2.8.1 OK OK OK
2.8.2 OK OK OK
2.8.3 OK OK OK
2.8.3-63-gb96997083 OK OK OK

Tarantool RelWithDebInfo + memcached RelWithDebInfo:

Tarantool memcached master memcached master + tests from PR #102 memcached PR #102
2.5.1 OK OK OK
2.5.2 OK OK OK
2.5.3 OK OK OK
2.6.1 OK OK OK
2.6.2 OK OK OK
2.6.3 OK OK OK
2.7.1 OK OK OK
2.7.2 OK OK OK
2.7.3 OK OK OK
2.8.1 OK OK OK
2.8.2 OK OK OK
2.8.3 OK OK OK
2.8.3-63-gb96997083 OK OK OK

Tests from PR #102 to run on memcached master are
test/common/instance_api.test.lua and test/common/module_api.test.lua from
commit 549ce31 ('memcached: use own slab
arena').

ibuf_* symbols

There is another problem with symbols clash:
tarantool/tarantool#6873. It is about ibuf_*
symbols and those symbols are NOT hid in 2.9.0-244-g5ceabb378.

We can attempt to extend the libsmall changes analysis and testing till recent
tarantool versions: current tarantool master is on
2.10.0-beta2-213-gcc768ea82 and it is not fixed there. However I can propose a hack.

We can just rename symbols in the module and skip the analysis.

PoC patch
diff --git a/small/ibuf.c b/small/ibuf.c
index fe3f441..ebcda67 100644
--- a/small/ibuf.c
+++ b/small/ibuf.c
@@ -34,7 +34,7 @@
 
 /** Initialize an input buffer. */
 void
-ibuf_create(struct ibuf *ibuf, struct slab_cache *slabc, size_t start_capacity)
+memcached_small_ibuf_create(struct ibuf *ibuf, struct slab_cache *slabc, size_t start_capacity)
 {
 	ibuf->slabc = slabc;
 	ibuf->buf = ibuf->rpos = ibuf->wpos = ibuf->end = NULL;
@@ -43,7 +43,7 @@ ibuf_create(struct ibuf *ibuf, struct slab_cache *slabc, size_t start_capacity)
 }
 
 void
-ibuf_destroy(struct ibuf *ibuf)
+memcached_small_ibuf_destroy(struct ibuf *ibuf)
 {
 	if (ibuf->buf) {
 		struct slab *slab = slab_from_data(ibuf->buf);
@@ -53,12 +53,12 @@ ibuf_destroy(struct ibuf *ibuf)
 
 /** Free memory allocated by this buffer */
 void
-ibuf_reinit(struct ibuf *ibuf)
+memcached_small_ibuf_reinit(struct ibuf *ibuf)
 {
 	struct slab_cache *slabc = ibuf->slabc;
 	size_t start_capacity = ibuf->start_capacity;
-	ibuf_destroy(ibuf);
-	ibuf_create(ibuf, slabc, start_capacity);
+	memcached_small_ibuf_destroy(ibuf);
+	memcached_small_ibuf_create(ibuf, slabc, start_capacity);
 }
 
 /**
@@ -67,7 +67,7 @@ ibuf_reinit(struct ibuf *ibuf)
  * the beginning.
  */
 void *
-ibuf_reserve_slow(struct ibuf *ibuf, size_t size)
+memcached_small_ibuf_reserve_slow(struct ibuf *ibuf, size_t size)
 {
 	assert(ibuf->wpos + size > ibuf->end);
 	size_t used = ibuf_used(ibuf);
diff --git a/small/ibuf.h b/small/ibuf.h
index 00d7781..691c821 100644
--- a/small/ibuf.h
+++ b/small/ibuf.h
@@ -69,13 +69,13 @@ struct ibuf
 };
 
 void
-ibuf_create(struct ibuf *ibuf, struct slab_cache *slabc, size_t start_capacity);
+memcached_small_ibuf_create(struct ibuf *ibuf, struct slab_cache *slabc, size_t start_capacity);
 
 void
-ibuf_destroy(struct ibuf *ibuf);
+memcached_small_ibuf_destroy(struct ibuf *ibuf);
 
 void
-ibuf_reinit(struct ibuf *ibuf);
+memcached_small_ibuf_reinit(struct ibuf *ibuf);
 
 /** How much data is read and is not parsed yet. */
 static inline size_t
@@ -119,14 +119,14 @@ ibuf_reset(struct ibuf *ibuf)
 }
 
 void *
-ibuf_reserve_slow(struct ibuf *ibuf, size_t size);
+memcached_small_ibuf_reserve_slow(struct ibuf *ibuf, size_t size);
 
 static inline void *
 ibuf_reserve(struct ibuf *ibuf, size_t size)
 {
 	if (ibuf->wpos + size <= ibuf->end)
 		return ibuf->wpos;
-	return ibuf_reserve_slow(ibuf, size);
+	return memcached_small_ibuf_reserve_slow(ibuf, size);
 }
 
 static inline void *
@@ -136,7 +136,7 @@ ibuf_alloc(struct ibuf *ibuf, size_t size)
 	if (ibuf->wpos + size <= ibuf->end)
 		ptr = ibuf->wpos;
 	else {
-		ptr = ibuf_reserve_slow(ibuf, size);
+		ptr = memcached_small_ibuf_reserve_slow(ibuf, size);
 		if (ptr == NULL)
 			return NULL;
 	}
diff --git a/memcached/internal/network.c b/memcached/internal/network.c
index 02126a6..d8deb8a 100644
--- a/memcached/internal/network.c
+++ b/memcached/internal/network.c
@@ -49,7 +49,7 @@ ibuf_new()
 {
 	void *ibuf = mempool_alloc(&ibuf_pool);
 	if (ibuf == NULL) return NULL;
-	ibuf_create((struct ibuf *)ibuf, memcached_slab_cache(), iobuf_readahead);
+	memcached_small_ibuf_create((struct ibuf *)ibuf, memcached_slab_cache(), iobuf_readahead);
 	return ibuf;
 }
 
@@ -65,7 +65,7 @@ obuf_new()
 void
 iobuf_delete(struct ibuf *ibuf, struct obuf *obuf)
 {
-	ibuf_destroy(ibuf);
+	memcached_small_ibuf_destroy(ibuf);
 	obuf_destroy(obuf);
 	mempool_free(&ibuf_pool, ibuf);
 	mempool_free(&obuf_pool, obuf);

Since ibuf.c and ibuf.h are small (not large, I mean) we can just copy them
into the module source code and rename functions.

After this I'll consider this issue as resolved.

Footnotes

  1. Here I got a fail, which is gone after re-run. It looks irrelevant to the
    symbols clash and I filed text/noreply.test.py fails sporadically #110 against it.

@Totktonada Totktonada self-assigned this Mar 28, 2022
Totktonada added a commit that referenced this issue Mar 28, 2022
Just copy and change includes. It is necessary to change function names
in a next commit.

Part of #59
Totktonada added a commit that referenced this issue Mar 28, 2022
Totktonada added a commit that referenced this issue Mar 28, 2022
See [1] for the problem root and [2] for analysis. In brief: `ibuf_*()`
symbols may clash with the same named symbols in tarantool, so it worth
to rename them to avoid effects of different binary layout: assertion
fails and memory corruptions.

For example, `ibuf_reserve_slow()` calls `slab_get()` and `slab_put()`.
If something will be changed in tarantool's slab cache, we can meet
problems in the module.

This patch just renames the `ibuf_*()` functions. It is the most simple
and durable workaround of the problem.

It is likely not necessary to rename inline functions, but since I'm not
dead sure, I renamed them all.

It is the last known problem from #59. All others are confirmed as safe
to ignore if we'll keep current libsmall version in the module (see the
analysis in [2]).

[1]: tarantool/tarantool#6873
[2]: #59 (comment)

Fixes #59
Totktonada added a commit that referenced this issue Mar 28, 2022
I wrote it mainly to clarify when the hack could be removed.

Follows up #59
Totktonada added a commit that referenced this issue Mar 28, 2022
See [1] for the problem root and [2] for analysis. In brief: `ibuf_*()`
symbols may clash with the same named symbols in tarantool, so it worth
to rename them to avoid effects of different binary layouts: assertion
fails and memory corruptions.

For example, `ibuf_reserve_slow()` calls `slab_get()` and `slab_put()`.
If something will be changed in tarantool's slab cache, we can meet
problems in the module.

This patch just renames the `ibuf_*()` functions. It is the most simple
and durable workaround of the problem.

It is likely not necessary to rename inline functions, but since I'm not
dead sure, I renamed them all.

It is the last known problem from #59. All others are confirmed as safe
to ignore if we'll keep current libsmall version in the module (see the
analysis in [2]).

[1]: tarantool/tarantool#6873
[2]: #59 (comment)

Fixes #59
Totktonada added a commit that referenced this issue Mar 28, 2022
I wrote it mainly to clarify when the hack could be removed.

Follows up #59
Totktonada added a commit that referenced this issue Mar 29, 2022
Just copy and change includes. It is necessary to change function names
in a next commit.

The source is the small version, which is bundled into the module:
1.1-63-g3df5050.

Part of #59
Totktonada added a commit that referenced this issue Mar 29, 2022
Totktonada added a commit that referenced this issue Mar 29, 2022
See [1] for the problem root and [2] for analysis. In brief: `ibuf_*()`
symbols may clash with the same named symbols in tarantool, so it worth
to rename them to avoid effects of different binary layouts: assertion
fails and memory corruptions.

For example, `ibuf_reserve_slow()` calls `slab_get()` and `slab_put()`.
If something will be changed in tarantool's slab cache, we can meet
problems in the module.

This patch just renames the `ibuf_*()` functions. It is the most simple
and durable workaround of the problem.

It is likely not necessary to rename inline functions, but since I'm not
dead sure, I renamed them all.

It is the last known problem from #59. All others are confirmed as safe
to ignore if we'll keep current libsmall version in the module (see the
analysis in [2]).

[1]: tarantool/tarantool#6873
[2]: #59 (comment)

Fixes #59
Totktonada added a commit that referenced this issue Mar 29, 2022
I wrote it mainly to clarify when the hack could be removed.

Follows up #59
ligurio added a commit that referenced this issue Apr 4, 2022
Historically memcached module uses slab cache created by Tarantool.
Fibers get access to it via call of function cord_slab_cache() that is a
part of Tarantool C API. The problem is happen when memcached and
Tarantool use different versions of Small library where ABI is broken.
Issues #59 and #96 are examples of such problems.

We decided use independent slab arena in memcached module to avoid such
problems in future and this patch implements it.

Below I'll describe what is important in switching to own arena.

memcached module uses different types of Small's allocators (ibuf and
obuf used for every network connection, one slab cache used per fiber).
There are two important things with used Small's allocators:

1. some allocators depends on other and sequence of allocations should
   be correct. README in small source code repository has a clear
   description of relationships between allocators [1].
2. some allocators are thread-safe and others not. slab arena is shared
   between all memcached instances, when slab cache allocated on top of
   slab arena is not thread-safe and must be used in scope of fiber.

memcached performs memory allocations and deallocations on different
stages and I would list all these stages explicitly:

- memcached module initialization
- memcached module deinitialization
- memcached instance gc
- memcached instance initialization
- memcached instance start
- memcached instance stop
- memcached instance deinitialization

Most part of these cases covered in tests
test/common/instance_api.test.lua and test/common/module_api.test.lua
that were added in previous commits. The exception here is gc that was
checked manually.

In tests function is_port_open() has been replaced to memcached
minimalistic client that do set value, get value with the same key and
compare both values. This check is more rigorous than check port
openess.

1. https://github.com/tarantool/small

Fixes #96
ligurio added a commit that referenced this issue Apr 5, 2022
Historically memcached module uses slab cache created by Tarantool.
Fibers get access to it via call of function cord_slab_cache() that is a
part of Tarantool C API. The problem is happen when memcached and
Tarantool use different versions of Small library where ABI is broken.
Issues #59 and #96 are examples of such problems.

We decided use independent slab arena in memcached module to avoid such
problems in future and this patch implements it.

Below I'll describe what is important in switching to own arena.

memcached module uses different types of Small's allocators (ibuf and
obuf used for every network connection, one slab cache used per fiber).
There are two important things with used Small's allocators:

1. some allocators depends on other and sequence of allocations should
   be correct. README in small source code repository has a clear
   description of relationships between allocators [1].
2. some allocators are thread-safe and others not. slab arena is shared
   between all memcached instances, when slab cache allocated on top of
   slab arena is not thread-safe and must be used in scope of fiber.

memcached performs memory allocations and deallocations on different
stages and I would list all these stages explicitly:

- memcached module initialization
- memcached module deinitialization
- memcached instance gc
- memcached instance initialization
- memcached instance start
- memcached instance stop
- memcached instance deinitialization

Most part of these cases covered in tests
test/common/instance_api.test.lua and test/common/module_api.test.lua
that were added in previous commits. The exception here is gc that was
checked manually.

In tests function is_port_open() has been replaced to memcached
minimalistic client that do set value, get value with the same key and
compare both values. This check is more rigorous than check port
openess.

1. https://github.com/tarantool/small

Fixes #96
ligurio added a commit that referenced this issue Apr 6, 2022
Historically memcached module uses slab cache created by Tarantool.
Fibers get access to it via call of function cord_slab_cache() that is a
part of Tarantool C API. The problem is happen when memcached and
Tarantool use different versions of Small library where ABI is broken.
Issues #59 and #96 are examples of such problems.

We decided use independent slab arena in memcached module to avoid such
problems in future and this patch implements it.

Below I'll describe what is important in switching to own arena.

memcached module uses different types of Small's allocators (ibuf and
obuf used for every network connection, one slab cache used per fiber).
There are two important things with used Small's allocators:

1. some allocators depends on other and sequence of allocations should
   be correct. README in small source code repository has a clear
   description of relationships between allocators [1].
2. some allocators are thread-safe and others not. slab arena is shared
   between all memcached instances, when slab cache allocated on top of
   slab arena is not thread-safe and must be used in scope of fiber.

memcached performs memory allocations and deallocations on different
stages and I would list all these stages explicitly:

- memcached module initialization
- memcached module deinitialization
- memcached instance gc
- memcached instance initialization
- memcached instance start
- memcached instance stop
- memcached instance deinitialization

Most part of these cases covered in tests
test/common/instance_api.test.lua and test/common/module_api.test.lua
that were added in previous commits. The exception here is gc that was
checked manually.

In tests function is_port_open() has been replaced to memcached
minimalistic client that do set value, get value with the same key and
compare both values. This check is more rigorous than check port
openess.

1. https://github.com/tarantool/small

Fixes #96
ligurio added a commit that referenced this issue Apr 6, 2022
Historically memcached module uses slab cache created by Tarantool.
Fibers get access to it via call of function cord_slab_cache() that is a
part of Tarantool C API. The problem is happen when memcached and
Tarantool use different versions of Small library where ABI is broken.
Issues #59 and #96 are examples of such problems.

We decided use independent slab arena in memcached module to avoid such
problems in future and this patch implements it.

Below I'll describe what is important in switching to own arena.

memcached module uses different types of Small's allocators (ibuf and
obuf used for every network connection, one slab cache used per fiber).
There are two important things with used Small's allocators:

1. some allocators depends on other and sequence of allocations should
   be correct. README in small source code repository has a clear
   description of relationships between allocators [1].
2. some allocators are thread-safe and others not. slab arena is shared
   between all memcached instances, when slab cache allocated on top of
   slab arena is not thread-safe and must be used in scope of fiber.

memcached performs memory allocations and deallocations on different
stages and I would list all these stages explicitly:

- memcached module initialization
- memcached module deinitialization
- memcached instance gc
- memcached instance initialization
- memcached instance start
- memcached instance stop
- memcached instance deinitialization

Most part of these cases covered in tests
test/common/instance_api.test.lua and test/common/module_api.test.lua
that were added in previous commits. The exception here is gc that was
checked manually.

In tests function is_port_open() has been replaced to memcached
minimalistic client that do set value, get value with the same key and
compare both values. This check is more rigorous than check port
openess.

1. https://github.com/tarantool/small

Fixes #96
ligurio added a commit that referenced this issue Apr 6, 2022
Historically memcached module uses slab cache created by Tarantool.
Fibers get access to it via call of function cord_slab_cache() that is a
part of Tarantool C API. The problem is happen when memcached and
Tarantool use different versions of Small library where ABI is broken.
Issues #59 and #96 are examples of such problems.

We decided use independent slab arena in memcached module to avoid such
problems in future and this patch implements it.

Below I'll describe what is important in switching to own arena.

memcached module uses different types of Small's allocators (ibuf and
obuf used for every network connection, one slab cache used per fiber).
There are two important things with used Small's allocators:

1. some allocators depends on other and sequence of allocations should
   be correct. README in small source code repository has a clear
   description of relationships between allocators [1].
2. some allocators are thread-safe and others not. slab arena is shared
   between all memcached instances, when slab cache allocated on top of
   slab arena is not thread-safe and must be used in scope of fiber.

memcached performs memory allocations and deallocations on different
stages and I would list all these stages explicitly:

- memcached module initialization
- memcached module deinitialization
- memcached instance gc
- memcached instance initialization
- memcached instance start
- memcached instance stop
- memcached instance deinitialization

Most part of these cases covered in tests
test/common/instance_api.test.lua and test/common/module_api.test.lua
that were added in previous commits. The exception here is gc that was
checked manually.

In tests function is_port_open() has been replaced to memcached
minimalistic client that do set value, get value with the same key and
compare both values. This check is more rigorous than check port
openess.

1. https://github.com/tarantool/small

Fixes #96
Totktonada added a commit that referenced this issue Apr 7, 2022
Just copy and change includes. It is necessary to change function names
in a next commit.

The source is the small version, which is bundled into the module:
1.1-63-g3df5050.

Part of #59
Totktonada added a commit that referenced this issue Apr 7, 2022
Totktonada added a commit that referenced this issue Apr 7, 2022
See [1] for the problem root and [2] for analysis. In brief: `ibuf_*()`
symbols may clash with the same named symbols in tarantool, so it worth
to rename them to avoid effects of different binary layouts: assertion
fails and memory corruptions.

For example, `ibuf_reserve_slow()` calls `slab_get()` and `slab_put()`.
If something will be changed in tarantool's slab cache, we can meet
problems in the module.

This patch just renames the `ibuf_*()` functions. It is the most simple
and durable workaround of the problem.

It is likely not necessary to rename inline functions, but since I'm not
dead sure, I renamed them all.

It is the last known problem from #59. All others are confirmed as safe
to ignore if we'll keep current libsmall version in the module (see the
analysis in [2]).

[1]: tarantool/tarantool#6873
[2]: #59 (comment)

Fixes #59
Totktonada added a commit that referenced this issue Apr 7, 2022
I wrote it mainly to clarify when the hack could be removed.

Follows up #59
Totktonada added a commit that referenced this issue Apr 27, 2022
Just copy and change includes. It is necessary to change function names
in a next commit.

The source is the small version, which is bundled into the module:
1.1-63-g3df5050.

Part of #59
Totktonada added a commit that referenced this issue Apr 27, 2022
Totktonada added a commit that referenced this issue Apr 27, 2022
See [1] for the problem root and [2] for analysis. In brief: `ibuf_*()`
symbols may clash with the same named symbols in tarantool, so it worth
to rename them to avoid effects of different binary layouts: assertion
fails and memory corruptions.

For example, `ibuf_reserve_slow()` calls `slab_get()` and `slab_put()`.
If something will be changed in tarantool's slab cache, we can meet
problems in the module.

This patch just renames the `ibuf_*()` functions. It is the most simple
and durable workaround of the problem.

It is likely not necessary to rename inline functions, but since I'm not
dead sure, I renamed them all.

It is the last known problem from #59. All others are confirmed as safe
to ignore if we'll keep current libsmall version in the module (see the
analysis in [2]).

[1]: tarantool/tarantool#6873
[2]: #59 (comment)

Fixes #59
Totktonada added a commit that referenced this issue Apr 27, 2022
I wrote it mainly to clarify when the hack could be removed.

Follows up #59
@Totktonada Totktonada added the 2sp label Apr 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
3 participants