
ok so there's a funny deallocation-access in code. i did glance at something indicating it was possibl-- anyway here i told asan to raise an abort signal when there is an error: #define __COMMON_SAN_DEFAULT_OPTIONS \ /* list options on startup \ "help=1" ":" */ \ /* read more options from file \ "include_if_exists=" ":" */ \ "print_stacktrace=true" \ ":" \ "report_error_type=true" \ ":" \ "strict_string_checks=true" \ ":" \ "abort_on_error=true" \ ":" \ "halt_on_error=true" extern "C" char const*__asan_default_options() { return __COMMON_SAN_DEFAULT_OPTIONS ":check_initialization_order=true" ":detect_invalid_pointer_pairs=2" ; } It's the "abort_on_error=true" that makes it do that. Usually these would be set with environment variables. The upshot is that I can have a familiar gdb interface to the failure happening. Program received signal SIGABRT, Aborted. __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 44 ./nptl/pthread_kill.c: No such file or directory. (gdb) bt #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 #1 0x00007ffff6a9de2f in __pthread_kill_internal (threadid=<optimized out>, signo=6) at ./nptl/pthread_kill.c:78 #2 0x00007ffff6a49d02 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #3 0x00007ffff6a324f0 in __GI_abort () at ./stdlib/abort.c:79 #4 0x00007ffff79144cf in __sanitizer::Abort () at ../../../../src/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp:143 #5 0x00007ffff7923f4c in __sanitizer::Die () at ../../../../src/libsanitizer/sanitizer_common/sanitizer_termination.cpp:58 #6 0x00007ffff78fee5f in __asan::ScopedInErrorReport::~ScopedInErrorReport (this=0x7fffffffaae6, __in_chrg=<optimized out>) at ../../../../src/libsanitizer/asan/asan_report.cpp:192 #7 0x00007ffff78fe4c0 in __asan::ReportGenericError (pc=93824993169577, bp=140737488336720, sp=sp@entry=140737488336712, addr=88441966559992, is_write=is_write@entry=false, access_size=8, fatal=true, exp=<optimized out>) at ../../../../src/libsanitizer/asan/asan_report.cpp:497 #8 0x00007ffff78fe62e in __asan::ReportGenericError (pc=<optimized out>, bp=bp@entry=140737488336720, sp=sp@entry=140737488336712, addr=<optimized out>, is_write=is_write@entry=false, access_size=access_size@entry=8, exp=<optimized out>, fatal=true) at ../../../../src/libsanitizer/asan/asan_report.cpp:497 #9 0x00007ffff78ff5cc in __asan::__asan_report_load8 (addr=<optimized out>) at ../../../../src/libsanitizer/asan/asan_rtl.cpp:131 #10 0x00005555556390a9 in AsymmetricStreamingXDiff::assert_no_dangling_pointers (this=0x7ffff4e01230) at diff_xdiff.cpp:765 #11 0x000055555563b403 in AsymmetricStreamingXDiff::extend_env (this=0x7ffff4e01230, line="c") at diff_xdiff.cpp:818 #12 0x000055555561267d in AsymmetricStreamingXDiff::diff(_ZN24AsymmetricStreamingXDiff4diffEN4zinc9generatorISt17basic_string_viewIcSt11char_traitsIcEES5_NS0_17use_allocator_argEEE.Frame *) (frame_ptr=0x512000000340) at diff_xdiff.cpp:695 #13 0x0000555555668068 in std::__n4861::coroutine_handle<zinc::__generator_promise_base<Diff, zinc::generator<Diff, Diff, zinc::use_allocator_arg> > >::resume (this=0x7ffff4937320) at /usr/include/c++/12/coroutine:244 #14 0x0000555555659ad4 in zinc::__generator_promise_base<Diff, zinc::generator<Diff, Diff, zinc::use_allocator_arg> >::resume (this=0x512000000350) at ../include/zinc/__generator.hpp:548 #15 0x000055555564b32e in zinc::generator<Diff, Diff, zinc::use_allocator_arg>::iterator::operator++ (this=0x7ffff4e01090) at ../include/zinc/__generator.hpp:822 #16 0x00005555556177d4 in (anonymous namespace)::AsymmetricStreamingXDiffAdapter::diff_main (this=0x7ffff5000030, a_="abc", b_="ab123c") at diff_xdiff.cpp:1029 #17 0x0000555555619bc9 in test_diff_xdiff () at diff_xdiff.cpp:1074 #18 0x0000555555620929 in main () at diff_xdiff.cpp:1108 (gdb) up 10 #10 0x00005555556390a9 in AsymmetricStreamingXDiff::assert_no_dangling_pointers (this=0x7ffff4e01230) at diff_xdiff.cpp:765 765 const auto old_file = std::string_view(xe.xdf1.recs[0]->ptr, xe.xdf1.recs[xe.xdf1.nrec-1]->ptr+xe.xdf1.recs[xe.xdf1.nrec-1]->size); (gdb) list 760 }); 761 return found; 762 }; 763 764 const auto& window = this->window; 765 const auto old_file = std::string_view(xe.xdf1.recs[0]->ptr, xe.xdf1.recs[xe.xdf1.nrec-1]->ptr+xe.xdf1.recs[xe.xdf1.nrec-1]->size); 766 767 768 // Iterate over both dynxdfs 769 for (size_t xdfi = 0; xdfi < 2; ++ xdfi) { (gdb) p xe.xdf1.recs[0]->ptr $2 = 0x7ffff4e01204 "c\n" (gdb) p xe.xdf1.recs[xe.xdf1.nrec-1]->ptr $3 = 0x7ffff4e01202 "b\nc\n" (gdb) p xe.xdf1.nrec $4 = 0 OOPS nrec is 0, probably because all the lines have been consumed. so this may likely actually be a bug in the function to assert there are no dangling pointers itself, which was mostly coded by deepseek3. [deepseek3 is a moe -- mixture of experts -- model. this is gratifying for the community as it is a no-brainer to do and saves a ton of compute, but the end result is that the model does not actually generalize as well as the larger more expensive models; contrariwise it is very good at passing tests]