* [Tarantool-patches] [PATCH luajit 0/2] Disable strcmp optimizations in Valgrind build
@ 2024-06-26 12:27 mandesero--- via Tarantool-patches
2024-06-26 12:27 ` [Tarantool-patches] [PATCH luajit 1/2] c: disable strcmp optimization " mandesero--- via Tarantool-patches
2024-06-26 12:27 ` [Tarantool-patches] [PATCH luajit 2/2] cmake: running tests under Valgrind, disable tests that failed under Valgrind mandesero--- via Tarantool-patches
0 siblings, 2 replies; 4+ messages in thread
From: mandesero--- via Tarantool-patches @ 2024-06-26 12:27 UTC (permalink / raw)
To: tarantool-patches, skaplun, m.kokryashkin; +Cc: mandesero
From: mandesero <mandesero@gmail.com>
In this Patchset, the optimization of strcmp is disabled during the LuaJIT build under Valgrind.
The string comparison is done byte-by-byte. Additionally, the memcmp functions, where strings
are compared, have been replaced to disable any potential internal optimizations.
Branch: https://github.com/tarantool/luajit/tree/mandesero/lj-3705-turn-off-strcmp-opt-in-debug
Issue: https://github.com/tarantool/tarantool/issues/3705
Some tests are failing under Valgrind due to the timer profiler (SIGPROF) or upon reaching
the maximum test duration, so they have been disabled.
mandesero (2):
c: disable strcmp optimization in Valgrind build
cmake: running tests under Valgrind, disable tests that failed under
Valgrind
.github/actions/setup-sanitizers/action.yml | 2 +-
.github/workflows/sanitizers-testing.yml | 53 +++++++++++++++++++++
src/lj_no_str_opt.supp | 16 +++++++
src/lj_str.c | 43 ++++++++++++++++-
test/CMakeLists.txt | 6 ++-
test/tarantool-tests/CMakeLists.txt | 17 +++++++
6 files changed, 133 insertions(+), 4 deletions(-)
create mode 100644 src/lj_no_str_opt.supp
--
2.34.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Tarantool-patches] [PATCH luajit 1/2] c: disable strcmp optimization in Valgrind build
2024-06-26 12:27 [Tarantool-patches] [PATCH luajit 0/2] Disable strcmp optimizations in Valgrind build mandesero--- via Tarantool-patches
@ 2024-06-26 12:27 ` mandesero--- via Tarantool-patches
2024-07-03 10:10 ` Sergey Kaplun via Tarantool-patches
2024-06-26 12:27 ` [Tarantool-patches] [PATCH luajit 2/2] cmake: running tests under Valgrind, disable tests that failed under Valgrind mandesero--- via Tarantool-patches
1 sibling, 1 reply; 4+ messages in thread
From: mandesero--- via Tarantool-patches @ 2024-06-26 12:27 UTC (permalink / raw)
To: tarantool-patches, skaplun, m.kokryashkin; +Cc: mandesero
From: mandesero <mandesero@gmail.com>
---
src/lj_str.c | 43 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 41 insertions(+), 2 deletions(-)
diff --git a/src/lj_str.c b/src/lj_str.c
index 321e8c4f..00cced03 100644
--- a/src/lj_str.c
+++ b/src/lj_str.c
@@ -26,10 +26,29 @@ static LJ_AINLINE int str_fastcmp(const char *a, const char *b, MSize len)
/* -- String helpers ------------------------------------------------------ */
+#if LUAJIT_USE_VALGRIND
+int lj_str_cmp_no_opt(const char *a, const char *b, MSize len)
+{
+ for (MSize i = 0; i < len; i++)
+ if (a[i] != b[i])
+ return 1;
+ return 0;
+}
+#endif
+
/* Ordered compare of strings. Assumes string data is 4-byte aligned. */
int32_t LJ_FASTCALL lj_str_cmp(GCstr *a, GCstr *b)
{
MSize i, n = a->len > b->len ? b->len : a->len;
+#if LUAJIT_USE_VALGRIND
+ const uint8_t *sa = (const uint8_t *)strdata(a);
+ const uint8_t *sb = (const uint8_t *)strdata(b);
+
+ for (i = 0; i < n; i++) {
+ if (sa[i] != sb[i])
+ return (uint8_t)sa[i] < (uint8_t)sb[i] ? -1 : 1;
+ }
+#else
for (i = 0; i < n; i += 4) {
/* Note: innocuous access up to end of string + 3. */
uint32_t va = *(const uint32_t *)(strdata(a)+i);
@@ -46,6 +65,7 @@ int32_t LJ_FASTCALL lj_str_cmp(GCstr *a, GCstr *b)
return va < vb ? -1 : 1;
}
}
+#endif
return (int32_t)(a->len - b->len);
}
@@ -53,6 +73,12 @@ int32_t LJ_FASTCALL lj_str_cmp(GCstr *a, GCstr *b)
static LJ_AINLINE int str_fastcmp(const char *a, const char *b, MSize len)
{
MSize i = 0;
+#if LUAJIT_USE_VALGRIND
+ for (i = 0; i < len; i++) {
+ if (a[i] != b[i])
+ return (uint8_t)a[i] < (uint8_t)b[i] ? -1 : 1;
+ }
+#else
lj_assertX(len > 0, "fast string compare with zero length");
lj_assertX((((uintptr_t)a+len-1) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4,
"fast string compare crossing page boundary");
@@ -68,6 +94,7 @@ static LJ_AINLINE int str_fastcmp(const char *a, const char *b, MSize len)
}
i += 4;
} while (i < len);
+#endif
return 0;
}
@@ -83,7 +110,11 @@ const char *lj_str_find(const char *s, const char *p, MSize slen, MSize plen)
while (slen) {
const char *q = (const char *)memchr(s, c, slen);
if (!q) break;
+#if LUAJIT_USE_VALGRIND
+ if (lj_str_cmp_no_opt(q+1, p, plen) == 0) return q;
+#else
if (memcmp(q+1, p, plen) == 0) return q;
+#endif
q++; slen -= (MSize)(q-s); s = q;
}
}
@@ -232,8 +263,13 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
} else { /* Slow path: end of string is too close to a page boundary. */
while (o != NULL) {
GCstr *sx = gco2str(o);
+#if LUAJIT_USE_VALGRIND
+ if (sx->hash == h && sx->len == len && inc_collision_hard() &&
+ lj_str_cmp_no_opt(str, strdata(sx), len) == 0) {
+#else
if (sx->hash == h && sx->len == len && inc_collision_hard() &&
memcmp(str, strdata(sx), len) == 0) {
+#endif
/* Resurrect if dead. Can only happen with fixstring() (keywords). */
if (isdead(g, o)) flipwhite(o);
g->strhash_hit++;
@@ -277,7 +313,11 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
} else { /* Slow path: end of string is too close to a page boundary. */
while (o != NULL) {
GCstr *sx = gco2str(o);
+#if LUAJIT_USE_VALGRIND
+ if (sx->hash == fh && sx->len == len && lj_str_cmp_no_opt(str, strdata(sx), len) == 0) {
+#else
if (sx->hash == fh && sx->len == len && memcmp(str, strdata(sx), len) == 0) {
+#endif
/* Resurrect if dead. Can only happen with fixstring() (keywords). */
if (isdead(g, o)) flipwhite(o);
g->strhash_hit++;
@@ -323,5 +363,4 @@ void LJ_FASTCALL lj_str_free(global_State *g, GCstr *s)
{
g->strnum--;
lj_mem_free(g, s, sizestring(s));
-}
-
+}
\ No newline at end of file
--
2.34.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Tarantool-patches] [PATCH luajit 2/2] cmake: running tests under Valgrind, disable tests that failed under Valgrind
2024-06-26 12:27 [Tarantool-patches] [PATCH luajit 0/2] Disable strcmp optimizations in Valgrind build mandesero--- via Tarantool-patches
2024-06-26 12:27 ` [Tarantool-patches] [PATCH luajit 1/2] c: disable strcmp optimization " mandesero--- via Tarantool-patches
@ 2024-06-26 12:27 ` mandesero--- via Tarantool-patches
1 sibling, 0 replies; 4+ messages in thread
From: mandesero--- via Tarantool-patches @ 2024-06-26 12:27 UTC (permalink / raw)
To: tarantool-patches, skaplun, m.kokryashkin; +Cc: mandesero
From: mandesero <mandesero@gmail.com>
---
.github/actions/setup-sanitizers/action.yml | 2 +-
.github/workflows/sanitizers-testing.yml | 53 +++++++++++++++++++++
src/lj_no_str_opt.supp | 16 +++++++
test/CMakeLists.txt | 6 ++-
test/tarantool-tests/CMakeLists.txt | 17 +++++++
5 files changed, 92 insertions(+), 2 deletions(-)
create mode 100644 src/lj_no_str_opt.supp
diff --git a/.github/actions/setup-sanitizers/action.yml b/.github/actions/setup-sanitizers/action.yml
index 8642d553..53f95075 100644
--- a/.github/actions/setup-sanitizers/action.yml
+++ b/.github/actions/setup-sanitizers/action.yml
@@ -20,7 +20,7 @@ runs:
- name: Install build and test dependencies
run: |
apt -y update
- apt -y install ${CC_NAME} libstdc++-10-dev cmake ninja-build make perl
+ apt -y install ${CC_NAME} libstdc++-10-dev cmake ninja-build make perl valgrind
shell: bash
env:
CC_NAME: ${{ inputs.cc_name }}
diff --git a/.github/workflows/sanitizers-testing.yml b/.github/workflows/sanitizers-testing.yml
index 154ebe40..85ccf580 100644
--- a/.github/workflows/sanitizers-testing.yml
+++ b/.github/workflows/sanitizers-testing.yml
@@ -93,3 +93,56 @@ jobs:
"
run: cmake --build . --parallel --target LuaJIT-test
working-directory: ${{ env.BUILDDIR }}
+
+
+ test-valgrind:
+ strategy:
+ fail-fast: false
+ matrix:
+ # XXX: Let's start with only Linux/x86_64
+ BUILDTYPE: [Debug, Release]
+ CC: [gcc-10, clang-11]
+ include:
+ - BUILDTYPE: Debug
+ CMAKEFLAGS: -DCMAKE_BUILD_TYPE=Debug -DLUA_USE_ASSERT=ON -DLUA_USE_APICHECK=ON
+ - BUILDTYPE: Release
+ CMAKEFLAGS: -DCMAKE_BUILD_TYPE=RelWithDebInfo
+ runs-on: [self-hosted, regular, Linux, x86_64]
+ name: >
+ LuaJIT with Valgrind (Linux/x86_64)
+ ${{ matrix.BUILDTYPE }}
+ CC:${{ matrix.CC }}
+ GC64:ON SYSMALLOC:ON
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ submodules: recursive
+ - name: setup Linux for sanitizers
+ uses: ./.github/actions/setup-sanitizers
+ with:
+ cc_name: ${{ matrix.CC }}
+ - name: configure
+ # XXX: LuaJIT configuration requires a couple of tweaks:
+ # LUAJIT_USE_SYSMALLOC=ON: Valgrind requires the use of
+ # a system-provided memory allocator (realloc) instead
+ # of the built-in memory allocator.
+ # configuration phase with -DLUAJIT_USE_SYSMALLOC=ON).
+ # For more info, see root CMakeLists.txt.
+ # LUAJIT_ENABLE_GC64=ON: LUAJIT_USE_SYSMALLOC cannot be
+ # enabled on x64 without GC64, since realloc usually
+ # doesn't return addresses in the right address range.
+ # For more info, see root CMakeLists.txt.
+ run: >
+ cmake -S . -B ${{ env.BUILDDIR }}
+ -G Ninja
+ ${{ matrix.CMAKEFLAGS }}
+ -DLUAJIT_USE_VALGRIND=ON
+ -DLUAJIT_USE_SYSMALLOC=ON
+ -DLUAJIT_ENABLE_GC64=ON
+ - name: build
+ run: cmake --build . --parallel
+ working-directory: ${{ env.BUILDDIR }}
+ - name: test
+ run: cmake --build . --parallel --target LuaJIT-test
+ working-directory: ${{ env.BUILDDIR }}
\ No newline at end of file
diff --git a/src/lj_no_str_opt.supp b/src/lj_no_str_opt.supp
new file mode 100644
index 00000000..1ec470f8
--- /dev/null
+++ b/src/lj_no_str_opt.supp
@@ -0,0 +1,16 @@
+# Valgrind suppression file for LuaJIT 2.0.
+{
+ Optimized string compare
+ Memcheck:Addr4
+ fun:lj_str_new
+}
+{
+ Optimized string compare
+ Memcheck:Addr1
+ fun:lj_str_new
+}
+{
+ Optimized string compare
+ Memcheck:Cond
+ fun:lj_str_new
+}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 19726f5a..fc2791f6 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -71,7 +71,11 @@ add_custom_target(${PROJECT_NAME}-lint DEPENDS
${PROJECT_NAME}-codespell
)
-set(LUAJIT_TEST_COMMAND "${LUAJIT_TEST_BINARY} -e dofile[[${LUAJIT_TEST_INIT}]]")
+if(LUAJIT_USE_VALGRIND)
+ set(LUAJIT_TEST_COMMAND "valgrind --suppressions=${CMAKE_SOURCE_DIR}/src/lj_no_str_opt.supp ${LUAJIT_TEST_BINARY} -e dofile[[${LUAJIT_TEST_INIT}]]")
+else()
+ set(LUAJIT_TEST_COMMAND "${LUAJIT_TEST_BINARY} -e dofile[[${LUAJIT_TEST_INIT}]]")
+endif()
separate_arguments(LUAJIT_TEST_COMMAND)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
diff --git a/test/tarantool-tests/CMakeLists.txt b/test/tarantool-tests/CMakeLists.txt
index d7c96078..ac09e993 100644
--- a/test/tarantool-tests/CMakeLists.txt
+++ b/test/tarantool-tests/CMakeLists.txt
@@ -121,9 +121,26 @@ add_test_suite_target(tarantool-tests
DEPENDS ${LUAJIT_TEST_DEPS} tarantool-tests-libs
)
+# Tests are disabled as they fail with Valgrind enabled due to SIGPROF
+# signals from the profiler or exceeding the maximum test duration time.
+list(APPEND valgrind_excluded_tests
+ "gh-5688-tool-cli-flag.test.lua"
+ "gh-5813-resolving-of-c-symbols.test.lua"
+ "gh-7264-add-proto-trace-sysprof-default.test.lua"
+ "gh-7745-oom-on-trace.test.lua"
+ "lj-1034-tabov-error-frame.test.lua"
+ "lj-512-profiler-hook-finalizers.test.lua"
+ "lj-726-profile-flush-close.test.lua"
+ "misclib-sysprof-lapi.test.lua"
+)
+
file(GLOB_RECURSE tests ${CMAKE_CURRENT_SOURCE_DIR} "*${LUA_TEST_SUFFIX}")
foreach(test_path ${tests})
get_filename_component(test_name ${test_path} NAME)
+ list(FIND valgrind_excluded_tests ${test_name} test_index)
+ if(LUAJIT_USE_VALGRIND AND NOT test_index EQUAL -1)
+ continue()
+ endif()
set(test_title "test/${TEST_SUITE_NAME}/${test_name}")
add_test(NAME ${test_title}
COMMAND ${LUAJIT_TEST_COMMAND} ${test_path}
--
2.34.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Tarantool-patches] [PATCH luajit 1/2] c: disable strcmp optimization in Valgrind build
2024-06-26 12:27 ` [Tarantool-patches] [PATCH luajit 1/2] c: disable strcmp optimization " mandesero--- via Tarantool-patches
@ 2024-07-03 10:10 ` Sergey Kaplun via Tarantool-patches
0 siblings, 0 replies; 4+ messages in thread
From: Sergey Kaplun via Tarantool-patches @ 2024-07-03 10:10 UTC (permalink / raw)
To: mandesero; +Cc: tarantool-patches
Hi, Maxim!
Thanks for the patch!
Please consider my comment below.
On 26.06.24, mandesero@gmail.com wrote:
> From: mandesero <mandesero@gmail.com>
>
> ---
> src/lj_str.c | 43 +++++++++++++++++++++++++++++++++++++++++--
AFAICS, the <src/lj.supp> contains Valgrind suppressions for
`lj_str_cmp()` and `str_fastcmp()`. The upstream politics until
ff34b48ddd6f2b3bdd26d6088662a214ba6b0288 ("Redesign and harden string
interning.") [1] is to use this file for all suppressions (see the
corresponding comments in the commit). So I suggest dropping this patch
and introducing testing with suppressions in the CI in another patch (as
it is done). Are there any objections to this?
[1]: https://github.com/LuaJIT/LuaJIT/commit/ff34b48ddd6f2b3bdd26d6088662a214ba6b0288
> 1 file changed, 41 insertions(+), 2 deletions(-)
>
> diff --git a/src/lj_str.c b/src/lj_str.c
> index 321e8c4f..00cced03 100644
> --- a/src/lj_str.c
> +++ b/src/lj_str.c
<snipped>
> --
> 2.34.1
>
--
Best regards,
Sergey Kaplun
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2024-07-29 17:51 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-06-26 12:27 [Tarantool-patches] [PATCH luajit 0/2] Disable strcmp optimizations in Valgrind build mandesero--- via Tarantool-patches
2024-06-26 12:27 ` [Tarantool-patches] [PATCH luajit 1/2] c: disable strcmp optimization " mandesero--- via Tarantool-patches
2024-07-03 10:10 ` Sergey Kaplun via Tarantool-patches
2024-06-26 12:27 ` [Tarantool-patches] [PATCH luajit 2/2] cmake: running tests under Valgrind, disable tests that failed under Valgrind mandesero--- via Tarantool-patches
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox