From: Gaute Hope <eg@gaute.vetsj.com>
To: David Bremner <david@tethera.net>, notmuch@notmuchmail.org
Subject: Re: talloc_abort in notmuch_thread_get_tags () when db has been modified
Date: Wed, 15 Feb 2017 22:58:51 +0000 [thread overview]
Message-ID: <1487199120.tz5yvag0pm.astroid@strange.none> (raw)
In-Reply-To: <87r3fmts2y.fsf@zancas.localnet>
[-- Attachment #1: Type: text/plain, Size: 1172 bytes --]
David Bremner writes on mars 7, 2016 13:01:
> Gaute Hope <eg@gaute.vetsj.com> writes:
>
>> as far as I can see, there is _no_ way to catch this error without
>> completely crashing the application. I would have to isolate this code
>> in a separate process or trap SIGABRT (which is certainly messy).
>
> I'm not sure what you expect libnotmuch to do here. There's a fatal
> "should not happen" error in the memory allocator; it isn't really the
> sort of thing one can recover from. It's also not in code we control.
>
> Of course _why_ this error is happening could still be notmuch's
> fault. Can you reproduce the problem under valgrind?
Hi again,
For future reference: Attached is C++ test code that demonstrates the problem
(at least on my setup). It is part of the astroid test suite.
The test-code must be adapted to your _test_ notmuch db.
To pick up on this again, this issue started cropping up more frequently
again, and I can't see a way currently to anticipate or recover from
this from a user application of the notmuch library. There seems to be
an XapianError, which may or may not be handled by notmuch.
Regards, Gaute
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: test_notmuch_standalone.cc --]
[-- Type: text/x-c++src; name=test_notmuch_standalone.cc, Size: 5178 bytes --]
# include <iostream>
# include <boost/filesystem.hpp>
# include <notmuch.h>
namespace bfs = boost::filesystem;
using std::cout;
using std::endl;
int main () {
bfs::path path_db = bfs::absolute (bfs::path("./test/mail/test_mail"));
notmuch_database_t * nm_db;
notmuch_status_t s =
notmuch_database_open (
path_db.c_str(),
notmuch_database_mode_t::NOTMUCH_DATABASE_MODE_READ_ONLY,
&nm_db);
cout << "db: running test query.." << endl;
notmuch_query_t * q = notmuch_query_create (nm_db, "*");
unsigned int c;
notmuch_status_t st = notmuch_query_count_threads_st (q, &c); // destructive
notmuch_query_destroy (q);
q = notmuch_query_create (nm_db, "*");
cout << "query: " << notmuch_query_get_query_string (q) << ", approx: "
<< c << " threads." << endl;
notmuch_threads_t * threads;
notmuch_thread_t * thread;
st = notmuch_query_search_threads_st (q, &threads);
std::string thread_id;
int i = 0;
for (; notmuch_threads_valid (threads);
notmuch_threads_move_to_next (threads)) {
thread = notmuch_threads_get (threads);
i++;
if (i == 3)
thread_id = notmuch_thread_get_thread_id (thread);
notmuch_thread_destroy (thread);
if (i == 3) break;
}
cout << "thread id to change: " << thread_id << ", thread no: " << i << endl;
notmuch_query_destroy (q);
/* restart query */
cout << "restarting query.." << endl;
q = notmuch_query_create (nm_db, "*");
st = notmuch_query_search_threads_st (q, &threads);
i = 0;
int stop = 2;
cout << "moving to thread: " << stop << endl;
for ( ; notmuch_threads_valid (threads);
notmuch_threads_move_to_next (threads))
{
thread = notmuch_threads_get (threads);
notmuch_thread_get_thread_id (thread);
i++;
cout << "tags: ";
/* get tags */
notmuch_tags_t *tags;
const char *tag;
for (tags = notmuch_thread_get_tags (thread);
notmuch_tags_valid (tags);
notmuch_tags_move_to_next (tags))
{
tag = notmuch_tags_get (tags);
cout << tag << " ";
}
cout << endl;
notmuch_thread_destroy (thread);
if (i == stop) break;
}
/* now open a new db instance, modify the already loaded thread and
* continue loading the original query */
notmuch_database_t * nm_db2;
s = notmuch_database_open (
path_db.c_str(),
notmuch_database_mode_t::NOTMUCH_DATABASE_MODE_READ_WRITE,
&nm_db2);
char qry_s[256];
sprintf (qry_s, "thread:%s", thread_id.c_str ());
notmuch_query_t * q2 = notmuch_query_create (nm_db2, qry_s);
notmuch_threads_t * ts2;
notmuch_thread_t * t2;
st = notmuch_query_search_threads_st (q2, &ts2);
for ( ; notmuch_threads_valid (ts2);
notmuch_threads_move_to_next (ts2))
{
t2 = notmuch_threads_get (ts2);
std::string thread_id = notmuch_thread_get_thread_id (t2);
/* remove unread tag */
notmuch_messages_t * ms = notmuch_thread_get_messages (t2);
notmuch_message_t * m;
for (; notmuch_messages_valid (ms); notmuch_messages_move_to_next (ms)) {
m = notmuch_messages_get (ms);
st = notmuch_message_remove_tag (m, "unread");
notmuch_message_destroy (m);
}
notmuch_messages_destroy (ms);
notmuch_thread_destroy (t2);
break;
}
notmuch_query_destroy (q2);
notmuch_database_close (nm_db2);
/* re-add unread tag */
s = notmuch_database_open (
path_db.c_str(),
notmuch_database_mode_t::NOTMUCH_DATABASE_MODE_READ_WRITE,
&nm_db2);
q2 = notmuch_query_create (nm_db2, qry_s);
st = notmuch_query_search_threads_st (q2, &ts2);
for ( ; notmuch_threads_valid (ts2);
notmuch_threads_move_to_next (ts2))
{
t2 = notmuch_threads_get (ts2);
std::string thread_id = notmuch_thread_get_thread_id (t2);
/* remove unread tag */
notmuch_messages_t * ms = notmuch_thread_get_messages (t2);
notmuch_message_t * m;
for (; notmuch_messages_valid (ms); notmuch_messages_move_to_next (ms)) {
m = notmuch_messages_get (ms);
st = notmuch_message_add_tag (m, "unread");
notmuch_message_destroy (m);
}
notmuch_messages_destroy (ms);
notmuch_thread_destroy (t2);
break;
}
notmuch_query_destroy (q2);
notmuch_database_close (nm_db2);
/* continue loading */
cout << "continue loading.." << endl;
for ( ; notmuch_threads_valid (threads);
notmuch_threads_move_to_next (threads))
{
if (threads == NULL) {
cout << "threads == NULL" << endl;
} else {
cout << "threads != NULL" << endl;
}
thread = notmuch_threads_get (threads);
cout << "loading: " << i;
std::string tid = notmuch_thread_get_thread_id (thread);
cout << ": " << tid << endl;
/* get tags */
notmuch_tags_t *tags;
const char *tag;
cout << "tags: ";
for (tags = notmuch_thread_get_tags (thread);
notmuch_tags_valid (tags);
notmuch_tags_move_to_next (tags))
{
tag = notmuch_tags_get (tags);
cout << tag << " ";
}
cout << endl;
i++;
notmuch_thread_destroy (thread);
}
notmuch_database_close (nm_db);
return 0;
}
next prev parent reply other threads:[~2017-02-15 22:58 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-18 12:45 talloc_abort in notmuch_thread_get_tags () when db has been modified Gaute Hope
2016-03-07 9:14 ` Gaute Hope
2016-03-07 12:01 ` David Bremner
2017-02-15 22:58 ` Gaute Hope [this message]
2017-02-17 12:28 ` David Bremner
2017-02-17 14:01 ` Gaute Hope
2017-02-17 15:35 ` David Bremner
2017-11-03 10:45 ` Gaute Hope
2017-11-03 12:02 ` Gaute Hope
2017-11-03 12:18 ` David Bremner
2017-11-03 12:50 ` Gaute Hope
-- strict thread matches above, loose matches on Subject: below --
2016-01-18 8:46 Gaute Hope
2016-01-18 12:25 ` David Bremner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://notmuchmail.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1487199120.tz5yvag0pm.astroid@strange.none \
--to=eg@gaute.vetsj.com \
--cc=david@tethera.net \
--cc=notmuch@notmuchmail.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://yhetil.org/notmuch.git/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).