Open Quuxplusone opened 5 years ago
Attached bug.cpp
(2310 bytes, text/x-csrc): Program that reproduces the problem
I think i accidentally almost fixed this in https://reviews.llvm.org/D65349.
Also note that running path-sensitive analysis with core checkers disabled is technically unsupported. In my case (beyond the link above) the problem was caused by exposing the destructor handling code to a situation that core checkers were not supposed to prevent, but in your case it's a pattern that core checkers were supposed to prevent. I.e., in reality the destructor would not have been called on this execution path, because it's preceded by a null pointer dereference. The null pointer dereference checker would have caught this and emitted a warning before even getting to the destructor.
If I enable the core checkers as well as bug.Analyzer, by adding the following code
{"core.CallAndMessage", true},
{"core.DivideZero", true},
{"core.DynamicTypePropagation", true},
{"core.NonNullParamChecker", true},
{"core.NonnilStringConstants", true},
{"core.NullDereference", true},
{"core.StackAddressEscape", true},
{"core.UndefinedBinaryOperatorResult", true},
{"core.VLASize", true},
{"core.builtin.BuiltinFunctions", true},
{"core.builtin.NoReturnFunctions", true},
{"core.uninitialized.ArraySubscript", true},
{"core.uninitialized.Assign", true},
{"core.uninitialized.Branch", true},
{"core.uninitialized.CapturedBlockVariable", true},
{"core.uninitialized.UndefReturn", true},
then I still get a crash, but a different one:
bug(27545,0x10eefd5c0) malloc: error for object 0x7ffee3f4b850: pointer being freed was not allocated bug(27545,0x10eefd5c0) malloc: set a breakpoint in malloc_error_break to debug Abort trap: 6
Debugger stack trace:
$ lldb -- ./bug (lldb) target create "./bug" Current executable set to './bug' (x86_64). (lldb) b malloc_error_break Breakpoint 1: where = libsystem_malloc.dylib`malloc_error_break, address = 0x0000000000017a67 (lldb) r Process 27565 launched: '/Users/ptomato/Documents/Coding/floatmage/bug' (x86_64) bug(27565,0x10154e5c0) malloc: error for object 0x7ffeefbff6f0: pointer being freed was not allocated bug(27565,0x10154e5c0) malloc: set a breakpoint in malloc_error_break to debug Process 27565 stopped
malloc_error_break libsystem_malloc.dylib
malloc_error_break:
-> 0x7fff7c23ea67 <+0>: pushq %rbp
0x7fff7c23ea68 <+1>: movq %rsp, %rbp
0x7fff7c23ea6b <+4>: nopmalloc_error_break frame #1: 0x00007fff7c2320ff libsystem_malloc.dylib
malloc_vreport + 437
frame #2: 0x00007fff7c231f2c libsystem_malloc.dylibmalloc_report + 151 frame #3: 0x0000000100002482 bug
BugAction::~BugAction() + 34
frame #4: 0x0000000100bf307f bugclang::tooling::FrontendActionFactory::runInvocation(std::__1::shared_ptr<clang::CompilerInvocation>, clang::FileManager*, std::__1::shared_ptr<clang::PCHContainerOperations>, clang::DiagnosticConsumer*) + 297 frame #5: 0x0000000100bf2de0 bug
clang::tooling::ToolInvocation::runInvocation(char const, clang::driver::Compilation, std::1::shared_ptrclang::tooling::ToolInvocation::run() + 1908 frame #7: 0x0000000100bf169e bug
clang::tooling::runToolOnCodeWithArgs(clang::FrontendAction*, llvm::Twine const&, llvm::IntrusiveRefCntPtrmain + 136 frame #11: 0x00007fff7c07e3d5 libdyld.dylib
start + 1As an aside, I'd rather not enable the null pointer checker on my real code, because an external library that I use unfortunately defines an assert macro that crashes by doing something like *((volatile int*)NULL) = __LINE__
which makes the null pointer checker go bananas on every assertion in that library's inline functions. It's something I can work around eventually, but it would be nice to not enable it, or failing that somehow tell the null pointer checker to ignore a certain macro.
Yup, i've seen this use-after-free as well, but it doesn't look like it's a Static Analyzer bug; it's happening when you're destroying your action
variable. If you allocate it on the heap and leak the problem doesn't happen (but you get a leak instead). I guess somebody does something wonky with the unique pointer.
Unfortunately there's currently no way to disable core checker warnings but keep doing their modeling work. It'll take some time to implement and unfortunately there aren't any easy hacks around it. You'll run into a lot more crashes due to disabling uninitialized variable checkers because a lot of other checkers aren't prepared to dealing with undefined values propagating their way :(
I see. Well, anyway, I worked around the problem by making an analyzer-friendly
shim for the offending header file and inserting it with
tooling::ClangTool::mapVirtualFile and
tooling::ClangTool::appendArgumentsAdjuster. In any case the crash is gone when
including all the core.* analyzers, thanks for the help.
I guess I should leave this open because there does seem to be an actual bug to
fix here?
Unfortunately there's currently no way to disable core checker warnings but keep doing their modeling work.
Hmm, actually, https://reviews.llvm.org/D66042.
bug.cpp
(2310 bytes, text/x-csrc)