SEGMFAULT with std::channel::send()

Folks, I need your help again.

I have a problem I am not able to understand and maybe I am just overlooking something.

Overall I get a segmentation fault from std::sync::mpsc::Sender<T>::send() that you can traceback below.

Thread 1 "redis-server" received signal SIGSEGV, Segmentation fault.
0x00007ffff4a36728 in core::sync::atomic::atomic_compare_exchange ()
    at /rustc/eae3437dfe991621e8afdc82734f4a172d7ddf9b/src/libcore/sync/atomic.rs:2182
2182    /rustc/eae3437dfe991621e8afdc82734f4a172d7ddf9b/src/libcore/sync/atomic.rs: No such file or directory.
(gdb) bt
#0  0x00007ffff4a36728 in core::sync::atomic::atomic_compare_exchange ()
    at /rustc/eae3437dfe991621e8afdc82734f4a172d7ddf9b/src/libcore/sync/atomic.rs:2182
#1  core::sync::atomic::AtomicBool::compare_exchange ()
    at /rustc/eae3437dfe991621e8afdc82734f4a172d7ddf9b/src/libcore/sync/atomic.rs:559
#2  core::sync::atomic::AtomicBool::compare_and_swap ()
    at /rustc/eae3437dfe991621e8afdc82734f4a172d7ddf9b/src/libcore/sync/atomic.rs:502
#3  std::sync::mpsc::blocking::SignalToken::signal () at src/libstd/sync/mpsc/blocking.rs:46
#4  0x00007ffff47744fc in std::sync::mpsc::Sender<T>::send (self=0x7fffffffd2d8, t=...)
    at /rustc/eae3437dfe991621e8afdc82734f4a172d7ddf9b/src/libstd/sync/mpsc/mod.rs:830
#5  0x00007ffff47867df in redis_sql::commands::Exec (ctx=0x7fffffffd750, argv=0x7ffff6c28f18, argc=3)
    at src/commands.rs:350
#6  0x000000000049f9cf in RedisModuleCommandDispatcher (c=<optimized out>) at module.c:509
#7  0x000000000042fc6f in call (c=c@entry=0x7ffff6d0dcc0, flags=flags@entry=15) at server.c:2437
#8  0x0000000000430337 in processCommand (c=0x7ffff6d0dcc0) at server.c:2729
#9  0x00000000004406a5 in processInputBuffer (c=0x7ffff6d0dcc0) at networking.c:1446
#10 0x00000000004298fd in aeProcessEvents (eventLoop=eventLoop@entry=0x7ffff6c300a0, flags=flags@entry=11)
    at ae.c:443
#11 0x0000000000429b2b in aeMain (eventLoop=0x7ffff6c300a0) at ae.c:501
#12 0x00000000004266de in main (argc=<optimized out>, argv=0x7fffffffda78) at server.c:4197

The code is quite complex and I wasn't able to isolate the issue in something smaller, but maybe some of you already saw something similar.

pub struct RedisDBKey {
    key: *mut rm::ffi::RedisModuleKey,
    // we don't want the field below to be dropped
    pub dbkey: std::mem::ManuallyDrop<DBKey>,
}

impl Drop for RedisDBKey {
    fn drop(&mut self) {
        // special behaviour for the key field
        debug!("***Closing the key.***");
        unsafe {
            rm::ffi::RedisModule_CloseKey.unwrap()(self.key);
        }
    }
}

impl RedisDBKey {
    pub fn new(context: &Context, name: &str) -> Result<Self, i32> {
        ....
            // we get a pointer from external library and then we .read() it
            let db_ptr = unsafe {
                rm::ffi::RedisModule_ModuleTypeGetValue.unwrap()(key)
                    as *mut DBKey
            };
            let dbkey =
                std::mem::ManuallyDrop::new(unsafe { db_ptr.read() });
            Ok(RedisDBKey { key, dbkey })
            .....
    }
}


....

let db = match RedisDBKey::new(&context, argvector[1]).unwrap()

let ch = &db.dbkey.tx;

match ch.send(cmd) // crash here

I don't understand if I am not respecting some invariant of channels or what else I am doing wrong.

Do you guys have any idea?

I also got valgrind leaks.

==25749== Invalid read of size 8                                                                                                                                                                                                              
==25749==    at 0x804EB5B: core::sync::atomic::atomic_swap (atomic.rs:2139)                                                                                                                                                                   
==25749==    by 0x806C189: core::sync::atomic::AtomicUsize::swap (atomic.rs:1360)                                                                                                                                                             
==25749==    by 0x8087494: std::sync::mpsc::oneshot::Packet<T>::drop_chan (oneshot.rs:229)                                                                                                                                                    
==25749==    by 0x806B575: <std::sync::mpsc::Sender<T> as core::ops::drop::Drop>::drop (mod.rs:900)                                                                                                                                           
==25749==    by 0x7F1ECA4: core::ptr::real_drop_in_place (mod.rs:175)                                                                                                                                                                         
==25749==    by 0x7F29643: std::sync::mpsc::Sender<T>::send (mod.rs:844)                                                                                                                                                                      
==25749==    by 0x7F34AE2: redis_sql::commands::Exec (commands.rs:350)                                                                                                                                                                        
==25749==    by 0x49F9CE: RedisModuleCommandDispatcher (module.c:509)                                                                                                                                                                         
==25749==    by 0x42FC6E: call (server.c:2437)                                                                                                                                                                                                
==25749==    by 0x430336: processCommand (server.c:2729)                                                                                                                                                                                      
==25749==    by 0x4406A4: processInputBuffer (networking.c:1446)                                                                                                                                                                              
==25749==    by 0x4298FC: aeProcessEvents (ae.c:443)                                                                                                                                                                                          
==25749==  Address 0x6060cf0 is 16 bytes inside a block of size 128 free'd                                                                                                                                                                    
==25749==    at 0x4031948: free (in /nix/store/gigcp3is1b9qih4zkk6vvfad305qdb1i-valgrind-3.14.0/lib/valgrind/vgpreload_memcheck-amd64-linux.so)                                                                                               
==25749==    by 0x80AE172: alloc::alloc::dealloc (alloc.rs:106)                                                                                                                                                                               
==25749==    by 0x80ADF59: <alloc::alloc::Global as core::alloc::Alloc>::dealloc (alloc.rs:177)                                                                                                                                               
==25749==    by 0x808FE73: alloc::sync::Arc<T>::drop_slow (sync.rs:707)                                                                                                                                                                       
==25749==    by 0x8090C77: <alloc::sync::Arc<T> as core::ops::drop::Drop>::drop (sync.rs:1225)                                                                                                                                                
==25749==    by 0x7F1DBFE: core::ptr::real_drop_in_place (mod.rs:175)                                                                                                                                                                         
==25749==    by 0x7F1DDCE: core::ptr::real_drop_in_place (mod.rs:175)                                                                                                                                                                         
==25749==    by 0x7F1D6CD: core::ptr::real_drop_in_place (mod.rs:175)                                                                                                                                                                         
==25749==    by 0x7F1E10B: core::ptr::real_drop_in_place (mod.rs:175)                                                                                                                                                                         
==25749==    by 0x7F29FC5: std::sync::mpsc::Receiver<T>::recv (mod.rs:1216)                                                                                                                                                                   
==25749==    by 0x7F2C82E: redisql_lib::redis::listen_and_execute (redis.rs:1038)                                                                                                                                                             
==25749==    by 0x7F32136: redis_sql::commands::CreateDB::{{closure}} (commands.rs:861)                                                                                                                                                       
==25749==  Block was alloc'd at                                                                                                                                                                                                               
==25749==    at 0x403079B: malloc (in /nix/store/gigcp3is1b9qih4zkk6vvfad305qdb1i-valgrind-3.14.0/lib/valgrind/vgpreload_memcheck-amd64-linux.so)                                                                                             
==25749==    by 0x7F204AB: alloc::alloc::alloc (alloc.rs:84)                                                                                                                                                                                  
==25749==    by 0x7F2041B: alloc::alloc::exchange_malloc (alloc.rs:206)                                                                                                                                                                       
==25749==    by 0x7F307ED: alloc::sync::Arc<T>::new (sync.rs:302)                                                                                                                                                                             
==25749==    by 0x7F2A273: std::sync::mpsc::channel (mod.rs:712)                                                       
==25749==    by 0x7F384E9: redis_sql::commands::CreateDB (commands.rs:851)                                             
==25749==    by 0x49F9CE: RedisModuleCommandDispatcher (module.c:509)                                                  
==25749==    by 0x42FC6E: call (server.c:2437)
==25749==    by 0x430336: processCommand (server.c:2729)
==25749==    by 0x4406A4: processInputBuffer (networking.c:1446)                                                       
==25749==    by 0x4298FC: aeProcessEvents (ae.c:443)
==25749==    by 0x429B2A: aeMain (ae.c:501)

There are many more but they look all quite similar...

I believe I got it!

I need to call ptr::write() if the read value was modified.