Subj : Re: Compiling from source To : Avon From : tenser Date : Mon Feb 01 2021 06:44:18 On 29 Jan 2021 at 09:21p, Avon pondered and said... Av> On 27 Jan 2021 at 02:59a, tenser pondered and said... Av> Av> te> Av> free(): double free detected in tcache 2 Av> te> Av> Aborted Av> Av> te> Well, a thing to try is to build it with one of the memory Av> te> sanitizers turned on and see if you can find the location Av> te> of the first free and the second; simply nil'ing out the pointer Av> te> will likely move past _that_ problem, as free(NULL) is a no-op. Av> te> But a more general problem is that none of this stuff was written Av> Av> Could you guide me as to how to do this? Av> Av> I'm looking at the man for g++ but so far unsure how to enable a Av> sanitizer mode. Av> Av> I'll keep poking and prodding :) Sure. First, perhaps it makes some sense to briefly describe how we go from source code to an executable image in a Unix-style environment, specifically using C/C++ compilers. For most medium- to large-size programs, the basic gist of it is that there are two logically separate steps: 1. Compilation. This is where we invoke the compiler on a source file (e.g., .c/.cc/.cpp/whatever). The compiler will read in the source file and, if it's a valid compilable file, will emit an "object file": this is the ".o" file we see after running the compiler. Usually the object file is in the "ELF" format. 2. Linking. This is where we invoke the linker on a set of object files and library archives to produce an executable image. The linker is responsible for combining object files and resolving references between then and libraries. Consider a simple program such as "Hello World": in C++, we would write: #include int main() { std::cout << "Hello, World!" << std::endl; return 0; } Suppose we put that text into "hello.cc". Then we can compile it by running two commands: % c++ -c hello.cc % c++ -o hello hello.o The first creates an object file called "hello.o". The second invokes the linker to create an executable file called "hello" that's created from whatever libraries the "c++" _driver command_ claims are necessary for C++ and from the "hello.o" object file. For simple programs like this, we can invoke the compiler driver program in such a way that the two steps are combined: % c++ -o hello hello.cc But note that these two independent steps still happen; I've used the term "driver command" for the `c++` program, because that's what it is: it's a program that actually invokes the real programs that make up the compiler and linker. Okay, why is any of this relevant? Because the sanitizers need support from both the compiler _and_ the linker. You tell both to enable sanitizer support by specifying command line flags to the driver program: to enable address sanitizer (which will help you find use-after-free and double-free bugs) you want to give the `-fsanitize=address` argument. So I could try to compile e.g. 'soup' as: % c++ -g -fsanitize=address -o soup foo.cpp bar.cpp etc.cpp In other words, edit the `makesoup` shell script and add `-g -fsanitize=address` to the `g++` or `c++` line. Then, when you run the resulting binary, it should tell you where the double-free occurs. This works since the `makesoup` shell script invokes the driver program so that it compiles _and_ links the `soup` source files in a single invocation. --- Mystic BBS v1.12 A46 2020/08/26 (Windows/32) * Origin: Agency BBS | Dunedin, New Zealand | agency.bbs.nz (21:1/101) .