KWARC / rust-libxml

Rust wrapper for libxml2
https://crates.io/crates/libxml
MIT License
76 stars 38 forks source link

"pointer being freed was not allocated" #50

Closed caldwell closed 5 years ago

caldwell commented 5 years ago

I have a test case in the drop_test branch of my github fork. The test commit is here. It's ugly. I tried to make it a more suitable testcase that you could use (smaller and use more obfuscated xml), but everything I did caused the problem to go away.

When I run cargo test on Mac OS X I get this:

tree_tests-249744ee950f6197(93787,0x700006f99000) malloc: *** error for object 0x7f8b87001236: pointer being freed was not allocated
tree_tests-249744ee950f6197(93787,0x700006f99000) malloc: *** set a breakpoint in malloc_error_break to debug

When I run on Debian, I get this:

free(): invalid pointer

I tried the breakpoint suggested in the mac error message and caught it. The backtrace is this:

* thread #2, name = 'flex_drop', stop reason = breakpoint 1.1
  * frame #0: 0x00007fff6315a0de libsystem_malloc.dylib`malloc_error_break
    frame #1: 0x00007fff6314d676 libsystem_malloc.dylib`malloc_vreport + 437
    frame #2: 0x00007fff6314d4a3 libsystem_malloc.dylib`malloc_report + 152
    frame #3: 0x00007fff62ca3792 libxml2.2.dylib`xmlFreeProp + 150
    frame #4: 0x00007fff62ce79a9 libxml2.2.dylib`xmlFreeNode + 307
    frame #5: 0x0000000100073221 tree_tests-249744ee950f6197`_$LT$libxml..tree..node.._Node$u20$as$u20$core..ops..drop..Drop$GT$::drop::hfac9065cf8822916(self=0x00000001003ef258) at node.rs:72:10
    frame #6: 0x00000001000719f5 tree_tests-249744ee950f6197`core::ptr::real_drop_in_place::h7f7f8242f4051cfa((null)=0x00000001003ef258) at ptr.rs:193
    frame #7: 0x00000001000719a5 tree_tests-249744ee950f6197`core::ptr::real_drop_in_place::h7d3944f20601a66a((null)=0x00000001003ef258) at ptr.rs:193
    frame #8: 0x0000000100071959 tree_tests-249744ee950f6197`core::ptr::real_drop_in_place::h7b25fc37c0635283((null)=0x00000001003ef250) at ptr.rs:193
    frame #9: 0x0000000100071489 tree_tests-249744ee950f6197`core::ptr::real_drop_in_place::h3273663067bf5143((null)=0x00000001003ef240) at ptr.rs:193
    frame #10: 0x000000010006abde tree_tests-249744ee950f6197`_$LT$alloc..rc..Rc$LT$T$GT$$u20$as$u20$core..ops..drop..Drop$GT$::drop::h0d1452789d9da09e [inlined] core::ptr::drop_in_place::he713afdf06d1726a(to_drop=0x00000001003ef240) at ptr.rs:183:4
    frame #11: 0x000000010006abd5 tree_tests-249744ee950f6197`_$LT$alloc..rc..Rc$LT$T$GT$$u20$as$u20$core..ops..drop..Drop$GT$::drop::h0d1452789d9da09e(self=0x0000000100829fb8) at rc.rs:861
    frame #12: 0x0000000100071ec5 tree_tests-249744ee950f6197`core::ptr::real_drop_in_place::hd11988989e4c8320((null)=0x0000000100829fb8) at ptr.rs:193
    frame #13: 0x00000001000712a5 tree_tests-249744ee950f6197`core::ptr::real_drop_in_place::h059cd52019b17386((null)=0x0000000100829fb8) at ptr.rs:193
    frame #14: 0x0000000100071c19 tree_tests-249744ee950f6197`core::ptr::real_drop_in_place::hb40400a6a2299f6d((null)=0x0000000100829fb0) at ptr.rs:193
    frame #15: 0x000000010006b824 tree_tests-249744ee950f6197`std::collections::hash::table::RawTable$LT$K$C$V$GT$::rev_drop_buckets::h641b04379c4b80b3 [inlined] core::ptr::drop_in_place::hb75486d4a1a356cc(to_drop=0x0000000100829fb0) at ptr.rs:183:4
    frame #16: 0x000000010006b81b tree_tests-249744ee950f6197`std::collections::hash::table::RawTable$LT$K$C$V$GT$::rev_drop_buckets::h641b04379c4b80b3(self=0x0000000100304e60) at table.rs:836
    frame #17: 0x0000000100070fd2 tree_tests-249744ee950f6197`_$LT$std..collections..hash..table..RawTable$LT$K$C$V$GT$$u20$as$u20$core..ops..drop..Drop$GT$::drop::hdb3d5376ec1745e5(self=0x0000000100304e60) at table.rs:1119:16
    frame #18: 0x00000001000713a5 tree_tests-249744ee950f6197`core::ptr::real_drop_in_place::h1be0a1e9f032c3f5((null)=0x0000000100304e60) at ptr.rs:193
    frame #19: 0x00000001000712c9 tree_tests-249744ee950f6197`core::ptr::real_drop_in_place::h0a9bd580f437cb9b((null)=0x0000000100304e50) at ptr.rs:193
    frame #20: 0x00000001000720fa tree_tests-249744ee950f6197`core::ptr::real_drop_in_place::hedb4b90123f3f789((null)=0x0000000100304e48) at ptr.rs:193
    frame #21: 0x0000000100072185 tree_tests-249744ee950f6197`core::ptr::real_drop_in_place::hee6d103f969acea1((null)=0x0000000100304e48) at ptr.rs:193
    frame #22: 0x0000000100071d79 tree_tests-249744ee950f6197`core::ptr::real_drop_in_place::hbf83bdd2e3a2d069((null)=0x0000000100304e40) at ptr.rs:193
    frame #23: 0x0000000100071b79 tree_tests-249744ee950f6197`core::ptr::real_drop_in_place::ha3bb801b7aa28ee0((null)=0x0000000100304e30) at ptr.rs:193
    frame #24: 0x000000010006ad5e tree_tests-249744ee950f6197`_$LT$alloc..rc..Rc$LT$T$GT$$u20$as$u20$core..ops..drop..Drop$GT$::drop::hf02e0c3ff1eb8844 [inlined] core::ptr::drop_in_place::h405055e68682654a(to_drop=0x0000000100304e30) at ptr.rs:183:4
    frame #25: 0x000000010006ad55 tree_tests-249744ee950f6197`_$LT$alloc..rc..Rc$LT$T$GT$$u20$as$u20$core..ops..drop..Drop$GT$::drop::hf02e0c3ff1eb8844(self=0x0000700006973618) at rc.rs:861
    frame #26: 0x000000010000ffc5 tree_tests-249744ee950f6197`core::ptr::real_drop_in_place::hf075550537525141((null)=0x0000700006973618) at ptr.rs:193
    frame #27: 0x000000010000ffa5 tree_tests-249744ee950f6197`core::ptr::real_drop_in_place::he27effd3de3d6a8c((null)=0x0000700006973618) at ptr.rs:193
    frame #28: 0x00000001000017b4 tree_tests-249744ee950f6197`tree_tests::flex_drop_fn_2::h0c7bad2f17434443(glyph_string=(data_ptr = "8assertion failed: !node_mock.is_text_node()assertion failed: node_mock.to_hashable() > 0assertion failed: null_node.is_null()assertion failed: second_null_node.is_null()examplekeyexamplevalueassertion failed: hello_element.set_attribute(key, value).is_ok()assertion failed: hello_element.get_content().is_empty()hello assertion failed: hello_element.append_text(\"hello \").is_ok()world!assertion failed: hello_element.append_text(\"world!\").is_ok()hello world!http://example.com/ns/mockassertion failed: mock_ns_result.is_ok()http://example.com/ns/secondassertion failed: second_ns_result.is_ok()assertion failed: root_node.get_namespace().is_none()assertion failed: root_node.set_namespace(&mock_ns_result.unwrap()).is_ok()assertion failed: active_ns_opt.is_some()mock1http://example.com/ns/mock1mock2http://example.com/ns/mock2\bassertion failed: root_node_opt.is_some()abcdeassertion failed: root_node.add_child(&mut a).is_ok()assertion failed: root_node.add_child(&mut b).is_ok()assertion failed: root_node.add_child(&mut "..., length = 1)) at tree_tests.rs:1201
    frame #29: 0x00000001000074b8 tree_tests-249744ee950f6197`tree_tests::flex_drop::hf8f3e9ebcdaacf37 at tree_tests.rs:1206:8
    frame #30: 0x000000010000e301 tree_tests-249744ee950f6197`tree_tests::flex_drop::_$u7b$$u7b$closure$u7d$$u7d$::h331952987d4e89ce((null)=0x0000700006973870) at tree_tests.rs:1204
    frame #31: 0x000000010000f6f1 tree_tests-249744ee950f6197`core::ops::function::FnOnce::call_once::h1d4e49fd071a3f4c((null)=closure @ 0x0000700006973870, (null)=<unavailable>) at function.rs:231:4
    frame #32: 0x000000010001a1c2 tree_tests-249744ee950f6197`call_box<(),closure> [inlined] {{closure}} at lib.rs:1513:29 [opt]
    frame #33: 0x000000010001a1bd tree_tests-249744ee950f6197`call_box<(),closure> [inlined] call_once<closure,()> at function.rs:231 [opt]
    frame #34: 0x000000010001a1bd tree_tests-249744ee950f6197`call_box<(),closure> at boxed.rs:749 [opt]
    frame #35: 0x000000010008a70f tree_tests-249744ee950f6197`__rust_maybe_catch_panic at lib.rs:87:7 [opt]
    frame #36: 0x00000001000356c7 tree_tests-249744ee950f6197`{{closure}} [inlined] try<(),std::panic::AssertUnwindSafe<alloc::boxed::Box<FnBox<()>>>> at panicking.rs:272:12 [opt]
    frame #37: 0x0000000100035682 tree_tests-249744ee950f6197`{{closure}} [inlined] catch_unwind<std::panic::AssertUnwindSafe<alloc::boxed::Box<FnBox<()>>>,()> at panic.rs:388 [opt]
    frame #38: 0x0000000100035682 tree_tests-249744ee950f6197`{{closure}} at lib.rs:1468 [opt]
    frame #39: 0x0000000100011925 tree_tests-249744ee950f6197`__rust_begin_short_backtrace<closure,()> at backtrace.rs:136:4 [opt]
    frame #40: 0x0000000100015ec5 tree_tests-249744ee950f6197`do_call<std::panic::AssertUnwindSafe<closure>,()> [inlined] {{closure}}<closure,()> at mod.rs:469:16 [opt]
    frame #41: 0x0000000100015eb2 tree_tests-249744ee950f6197`do_call<std::panic::AssertUnwindSafe<closure>,()> [inlined] call_once<(),closure> at panic.rs:309 [opt]
    frame #42: 0x0000000100015eb2 tree_tests-249744ee950f6197`do_call<std::panic::AssertUnwindSafe<closure>,()> at panicking.rs:293 [opt]
    frame #43: 0x000000010008a70f tree_tests-249744ee950f6197`__rust_maybe_catch_panic at lib.rs:87:7 [opt]
    frame #44: 0x000000010001a2e5 tree_tests-249744ee950f6197`call_box<(),closure> [inlined] try<(),std::panic::AssertUnwindSafe<closure>> at panicking.rs:272:12 [opt]
    frame #45: 0x000000010001a2ac tree_tests-249744ee950f6197`call_box<(),closure> [inlined] catch_unwind<std::panic::AssertUnwindSafe<closure>,()> at panic.rs:388 [opt]
    frame #46: 0x000000010001a2ac tree_tests-249744ee950f6197`call_box<(),closure> [inlined] {{closure}}<closure,()> at mod.rs:468 [opt]
    frame #47: 0x000000010001a26e tree_tests-249744ee950f6197`call_box<(),closure> at boxed.rs:749 [opt]
    frame #48: 0x000000010008a04c tree_tests-249744ee950f6197`thread_start [inlined] call_once<(),()> at boxed.rs:759:8 [opt]
    frame #49: 0x000000010008a049 tree_tests-249744ee950f6197`thread_start [inlined] start_thread at thread.rs:14 [opt]
    frame #50: 0x0000000100089fce tree_tests-249744ee950f6197`thread_start at thread.rs:80 [opt]
    frame #51: 0x00007fff63189305 libsystem_pthread.dylib`_pthread_body + 126
    frame #52: 0x00007fff6318c26f libsystem_pthread.dylib`_pthread_start + 70
    frame #53: 0x00007fff63188415 libsystem_pthread.dylib`thread_start + 13

This makes me think it's the drop code for _Node in node.rs. I tried looking at it but as I'm not really familiar with the code, there was nothing super obvious to me.

dginev commented 5 years ago

Interesting case. All you need is to keep on of the c elements and the unlink_node call and I can reproduce.

It seems that unlinking a node that comes from an xpath evaluation isn't implemented correctly, will try to fish out which is the exact misalignment from the libxml2 recommendation.

dginev commented 5 years ago

I may have a fix in #51 , will run a couple of extra tests tomorrow and land it. Let me know if you spot any other issues!

caldwell commented 5 years ago

That was impressively quick debugging :-). I compiled my original code against your PR #51 branch and do not see any more malloc asserts. Thanks!