The test fails reliably when Notmuch is compiled as such: ./configure make CFLAGS=-fsanitize=thread LDFLAGS=-fsanitize=thread It's still unclear how the test suite could be run with the correct compilation flags.
Output: T810-tsan: Testing run code with TSan enabled against the library PASS create PASS query FAIL sexp query --- T810-tsan.3.EXPECTED 2023-04-03 19:53:04.400771102 +0000 +++ T810-tsan.3.OUTPUT 2023-04-03 19:53:04.402771109 +0000 @@ -1,2 +1,44 @@ == stdout == == stderr == +================== +WARNING: ThreadSanitizer: data race (pid=21372) + Read of size 4 at 0x7b1000000188 by thread T2: + #0 Xapian::Internal::intrusive_ptr<Xapian::Query::Internal>::intrusive_ptr(Xapian::Internal::intrusive_ptr<Xapian::Query::Internal> const&) .../xapian/intrusive_ptr.h:107 (libnotmuch.so.5+0x3017b) + #1 Xapian::Query::Query(Xapian::Query const&) .../xapian/query.h:328 (libnotmuch.so.5+0x2fcbe) + #2 _sexp_to_xapian_query lib/parse-sexp.cc:707 (libnotmuch.so.5+0x43f1f) + #3 _notmuch_sexp_string_to_xapian_query(_notmuch_database*, char const*, Xapian::Query&) lib/parse-sexp.cc:729 (libnotmuch.so.5+0x44207) + #4 _notmuch_query_ensure_parsed_sexpr lib/query.cc:240 (libnotmuch.so.5+0x2c59e) + #5 _notmuch_query_ensure_parsed lib/query.cc:258 (libnotmuch.so.5+0x2c646) + #6 _notmuch_query_search_documents lib/query.cc:362 (libnotmuch.so.5+0x2cc0e) + #7 notmuch_query_search_messages lib/query.cc:350 (libnotmuch.so.5+0x2cb76) + #8 thread CWD/test2.c:17 (test2+0x4012f4) + + Previous write of size 4 at 0x7b1000000188 by thread T1: + #0 Xapian::Internal::intrusive_ptr<Xapian::Query::Internal>::intrusive_ptr(Xapian::Internal::intrusive_ptr<Xapian::Query::Internal> const&) .../xapian/intrusive_ptr.h:107 (libnotmuch.so.5+0x3018e) + #1 Xapian::Query::Query(Xapian::Query const&) .../xapian/query.h:328 (libnotmuch.so.5+0x2fcbe) + #2 _sexp_to_xapian_query lib/parse-sexp.cc:707 (libnotmuch.so.5+0x43f1f) + #3 _notmuch_sexp_string_to_xapian_query(_notmuch_database*, char const*, Xapian::Query&) lib/parse-sexp.cc:729 (libnotmuch.so.5+0x44207) + #4 _notmuch_query_ensure_parsed_sexpr lib/query.cc:240 (libnotmuch.so.5+0x2c59e) + #5 _notmuch_query_ensure_parsed lib/query.cc:258 (libnotmuch.so.5+0x2c646) + #6 _notmuch_query_search_documents lib/query.cc:362 (libnotmuch.so.5+0x2cc0e) + #7 notmuch_query_search_messages lib/query.cc:350 (libnotmuch.so.5+0x2cb76) + #8 thread CWD/test2.c:17 (test2+0x4012f4) + + Location is heap block of size 56 at 0x7b1000000180 allocated by main thread: + #0 operator new(unsigned long) <null> (libtsan.so.2+0x8ba83) + #1 Xapian::Query::Query(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int, unsigned int) <null> (libxapian.so.30+0x9f200) + #2 __static_initialization_and_destruction_0(int, int) <null> (libxapian.so.30+0xa27ac) + #3 _GLOBAL__sub_I_query.cc <null> (libxapian.so.30+0xa286d) + #4 call_init <null> (ld-linux-x86-64.so.2+0x5e1d) + + Thread T2 (tid=21375, running) created by main thread at: + #0 pthread_create <null> (libtsan.so.2+0x62de6) + #1 main CWD/test2.c:24 (test2+0x4013ba) + + Thread T1 (tid=21374, running) created by main thread at: + #0 pthread_create <null> (libtsan.so.2+0x62de6) + #1 main CWD/test2.c:23 (test2+0x401380) + +SUMMARY: ThreadSanitizer: data race .../xapian/intrusive_ptr.h:107 in Xapian::Internal::intrusive_ptr<Xapian::Query::Internal>::intrusive_ptr(Xapian::Internal::intrusive_ptr<Xapian::Query::Internal> const&) +================== +ThreadSanitizer: reported 1 warnings --- test/T810-tsan.sh | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/test/T810-tsan.sh b/test/T810-tsan.sh index 7e877b27..de98c0a9 100755 --- a/test/T810-tsan.sh +++ b/test/T810-tsan.sh @@ -4,7 +4,8 @@ test_directory=$(cd "$(dirname "${BASH_SOURCE[0]}")" > /dev/null && pwd) test_description='run code with TSan enabled against the library' # Note it is hard to ensure race conditions are deterministic so this -# only provides best effort detection. +# only provides best effort detection. Compile Notmuch with +# make CFLAGS=-fsanitize=thread LDFLAGS=-fsanitize=thread . "$test_directory"/test-lib.sh || exit 1 @@ -89,4 +90,44 @@ cat <<EOF > EXPECTED EOF test_expect_equal_file EXPECTED OUTPUT +if [ $NOTMUCH_HAVE_SFSEXP -eq 1 ]; then + test_begin_subtest "sexp query" + test_subtest_known_broken + test_C ${MAIL_DIR} ${MAIL_DIR}-2 <<EOF +#include <notmuch-test.h> +#include <pthread.h> + +void *thread (void *arg) { + char *mail_dir = arg; + notmuch_database_t *db; + /* + * Query generation from s-expression used the tread-unsafe + * Xapian::Query::MatchAll. + */ + EXPECT0(notmuch_database_open_with_config (mail_dir, + NOTMUCH_DATABASE_MODE_READ_ONLY, + NULL, NULL, &db, NULL)); + notmuch_query_t *query; + EXPECT0(notmuch_query_create_with_syntax (db, "(from *)", NOTMUCH_QUERY_SYNTAX_SEXP, &query)); + notmuch_messages_t *messages; + EXPECT0(notmuch_query_search_messages (query, &messages)); + return NULL; +} + +int main (int argc, char **argv) { + pthread_t t1, t2; + EXPECT0(pthread_create (&t1, NULL, thread, argv[1])); + EXPECT0(pthread_create (&t2, NULL, thread, argv[2])); + EXPECT0(pthread_join (t1, NULL)); + EXPECT0(pthread_join (t2, NULL)); + return 0; +} +EOF + cat <<EOF > EXPECTED +== stdout == +== stderr == +EOF + test_expect_equal_file EXPECTED OUTPUT +fi + test_done _______________________________________________ notmuch mailing list -- notmuch@notmuchmail.org To unsubscribe send an email to notmuch-le...@notmuchmail.org