Skip to content
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

task sync crashes with SIGPIPE #3624

Closed
gnojus opened this issue Sep 14, 2024 · 6 comments · Fixed by #3627
Closed

task sync crashes with SIGPIPE #3624

gnojus opened this issue Sep 14, 2024 · 6 comments · Fixed by #3627
Assignees
Milestone

Comments

@gnojus
Copy link

gnojus commented Sep 14, 2024

With somewhat invalid server sync configuration (sync.server.url pointing to a service that is not a taskchampion server) running task sync results in the process crashing with unix return code 141 (SIGPIPE), without printing any output to stdout/stderr. I assume the bug is in the external taskwarrior rust lib.

task versoin 3.1.0

@djmitche
Copy link
Collaborator

Hm, I just get

Failed to synchronize with server                                                                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                               
shell returned 2                                                                                                                                                                                                                                                                                                               

can you give more steps to reproduce, or better yet an strace of where the SIGPIPE occurs?

Also, can you please show how you're running task sync? SIGPIPE is typically associated with UNIX pipes, and Taskwarrior does not use those. Are you running something like task sync | <some command>?

@gnojus
Copy link
Author

gnojus commented Sep 19, 2024

It was hard to create a simple reproducer, but this should work:

  • move your task config: mv ~/.config/task/taskchampion.sqlite3 ~/.config/task/taskchampion.sqlite3.bk
  • add some unsynced backlog: for i in {0..1000}; do task add some fake task no $i; done
  • set the sync url to https://caddyserver.com/taskw/
  • run task sync

And this is the stack trace:

* thread #1, name = 'task', stop reason = signal SIGPIPE
  * frame #0: 0x00007ffff7b336f4 libc.so.6`writev + 20
    frame #1: 0x0000000000c8a74c task`_$LT$std..net..tcp..TcpStream$u20$as$u20$std..io..Write$GT$::write_vectored::h01796ceb5899e098 [inlined] std::sys::pal::unix::fd::FileDesc::write_vectored::h1771fd34b289caf5 at fd.rs:297:13
    frame #2: 0x0000000000c8a736 task`_$LT$std..net..tcp..TcpStream$u20$as$u20$std..io..Write$GT$::write_vectored::h01796ceb5899e098 [inlined] std::sys::pal::unix::net::Socket::write_vectored::h5761f22114f9fa19 at net.rs:349:9
    frame #3: 0x0000000000c8a736 task`_$LT$std..net..tcp..TcpStream$u20$as$u20$std..io..Write$GT$::write_vectored::h01796ceb5899e098 [inlined] std::sys_common::net::TcpStream::write_vectored::h3be77aff68416b47 at net.rs:303:9
    frame #4: 0x0000000000c8a736 task`_$LT$std..net..tcp..TcpStream$u20$as$u20$std..io..Write$GT$::write_vectored::h01796ceb5899e098 at tcp.rs:642:9
    frame #5: 0x00000000006f7978 task`rustls::vecbuf::ChunkVecBuffer::write_to::hb675df699816cf7a + 472
    frame #6: 0x00000000006b2621 task`rustls::conn::ConnectionCommon$LT$Data$GT$::complete_io::h3f72d9ac52703021 + 209
    frame #7: 0x00000000006b3c17 task`_$LT$rustls..stream..Stream$LT$C$C$T$GT$$u20$as$u20$std..io..Write$GT$::write::hd5bbf1637fb23518 + 87
    frame #8: 0x000000000069f8af task`_$LT$ureq..rtls..RustlsStream$u20$as$u20$std..io..Write$GT$::write::h538bf546b87f9aaa + 31
    frame #9: 0x00000000006a0132 task`std::io::Write::write_all::h9694e1f6fd613978 + 98
    frame #10: 0x00000000006b92a2 task`std::io::copy::stack_buffer_copy::h4751e70477f44635 + 274
    frame #11: 0x00000000006bb106 task`ureq::body::send_body::h0aed3ce946b1e396 + 646
    frame #12: 0x0000000000d78887 task`ureq::unit::connect_inner::hafef95ff878b21c2 + 1319
    frame #13: 0x0000000000d7728d task`ureq::unit::connect::h7fa68a3ebe6033ab + 221
    frame #14: 0x00000000006ae270 task`ureq::request::Request::do_call::_$u7b$$u7b$closure$u7d$$u7d$::h97a40ab23c6f78e1 + 384
    frame #15: 0x00000000006ada77 task`ureq::request::Request::do_call::hc1e883cdf43c1ebd + 1287
    frame #16: 0x00000000006ae7dc task`ureq::request::Request::send_bytes::hd9f3615fe5d86643 + 44
    frame #17: 0x000000000064e0b0 task`_$LT$taskchampion..server..sync..SyncServer$u20$as$u20$taskchampion..server..types..Server$GT$::add_version::h54b33fd65917aa8a + 1072
    frame #18: 0x00000000006812bc task`taskchampion::taskdb::sync::sync::hcc30e39b8cab2d5c + 5996
    frame #19: 0x000000000065737d task`taskchampion::taskdb::TaskDb::sync::h0cb5d59b328d8fff + 77
    frame #20: 0x000000000069357a task`taskchampion::replica::Replica::sync::h56647844e61238e3 + 26
    frame #21: 0x0000000000636491 task`tc_replica_sync + 129
    frame #22: 0x00000000004dd199 task`tc::Replica::sync(tc::Server, bool) + 25
    frame #23: 0x0000000000490485 task`TDB2::sync(tc::Server, bool) + 37
    frame #24: 0x000000000059f63c task`CmdSync::execute(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&) + 2524
    frame #25: 0x000000000046406c task`Context::dispatch(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&) + 412
    frame #26: 0x00000000004646b8 task`Context::run() + 72
    frame #27: 0x000000000045a614 task`main + 116
    frame #28: 0x00007ffff7a4614a libc.so.6`__libc_start_call_main + 122
    frame #29: 0x00007ffff7a4620b libc.so.6`__libc_start_main@@GLIBC_2.34 + 139
    frame #30: 0x000000000045c7a5 task`_start + 37

@djmitche
Copy link
Collaborator

Thanks! I can reproduce with that result! I filed algesten/ureq#819 to see if there's a good way to handle this, as a bit of searching didn't find any suggestions.

@djmitche djmitche self-assigned this Sep 21, 2024
@djmitche
Copy link
Collaborator

They would like a simple reproduction with ureq alone. I won't get a chance to work on that for a bit, if anyone else wants to try.

@djmitche
Copy link
Collaborator

I built a little test script in the taskchampion crate, and this returned a Result::Err from Replica::sync, so this has something to do with how signals are handled in Taskwarrior.

@djmitche
Copy link
Collaborator

diff --git src/main.cpp src/main.cpp
index cbdeb0994..3d4a3d1b1 100644
--- src/main.cpp
+++ src/main.cpp
@@ -24,25 +24,36 @@
 //
 ////////////////////////////////////////////////////////////////////////////////
 
 #include <cmake.h>
 // cmake.h include header must come first
 
 #include <Context.h>
 #include <rust/cxx.h>
+#include <signal.h>
 
 #include <cstring>
 #include <iostream>
 #include <new>
 #include <regex>
 
 ////////////////////////////////////////////////////////////////////////////////
 int main(int argc, const char** argv) {
   int status{0};
+  struct sigaction sa;
+
+  // Initialize the signal action structure
+  sa.sa_handler = SIG_IGN;  // Set the handler to ignore SIGPIPE
+  sa.sa_flags = 0;
+
+  // Set the signal handler for SIGPIPE
+  if (sigaction(SIGPIPE, &sa, NULL) == -1) {
+    return 1;
+  }
 
   Context globalContext;
   Context::setContext(&globalContext);
 
   // Lightweight version checking that doesn't require initialization or any I/O.
   if (argc == 2 && !strcmp(argv[1], "--version")) {
     std::cout << VERSION << "\n";
   } else {

seems to help -- the error message is shown instead of dying on the signal. This matches what the Rust runtime does at startup.

I'm not sure that's the right way to set a signal handler, though.

@djmitche djmitche moved this from Backlog to In review in Taskwarrior Development Sep 22, 2024
@djmitche djmitche added this to the v3.2.0 milestone Sep 22, 2024
@github-project-automation github-project-automation bot moved this from In review to Done in Taskwarrior Development Sep 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

2 participants