It's in the libstdc++-v3 directory in the g++ (gcc-c++) sources.
Yes, you have to build the whole of GCC, but once you've done that you only need to rebuild the libstdc++ part.
Building GCC is described at http://gcc.gnu.org/wiki/InstallingGCC
The libstdc++ sources are in the libstdc++-v3 directory. The parallel algorithms are in libstdc++-v3/include/parallel, they are templates so all the code is in headers. The small amount of non-header code is in libstdc++-v3/src/c++98/parallel-settings.cc
After configuring and building the whole of GCC as normal, you can rebuild libstdc++ by running make in the $TARGET/libstdc++-v3 directory (where $TARGET is something like x86_64-pc-linux-gnu).
By default the makefiles don't have proper dependencies that cause objects to be rebuilt after headers change, so you might need to do make clean then make again to get your changes to be picked up.
Minimal step-by-step example
Compile GCC from source. Condensed commands:
sudo apt-get build-dep gcc
git clone git://gcc.gnu.org/git/gcc.git
cd gcc
git checkout gcc-6_4_0-release
./contrib/download_prerequisites
mkdir build
cd build
../configure --enable-languages=c,c++ --prefix="$(pwd)/install"
make -j`nproc`
make install
Wait from 30-minutes to two hours. Now let's use this test program a.cpp:
#include <cassert>
#include <queue>
int main() {
std::priority_queue<int> q;
q.emplace(2);
q.emplace(1);
q.emplace(3);
assert(q.top() == 3);
q.pop();
assert(q.top() == 2);
q.pop();
assert(q.top() == 1);
q.pop();
}
First compile and run it to ensure that the initial compilation worked:
gcc/build/install/bin/g++ -g -std=c++11 -O0 -o a.out ./a.cpp
./a.out
Now let's hack up the priority_queue constructor.
First, you can find the actual constructor easily with GDB as explained at: When should I use make_heap vs. Priority Queue?
So we hack it up with this patch:
diff --git a/libstdc++-v3/include/bits/stl_queue.h b/libstdc++-v3/include/bits/stl_queue.h
index 5d255e7300b..deec7bc4d99 100644
--- a/libstdc++-v3/include/bits/stl_queue.h
+++ b/libstdc++-v3/include/bits/stl_queue.h
@@ -61,6 +61,7 @@
#if __cplusplus >= 201103L
# include <bits/uses_allocator.h>
#endif
+#include <iostream>
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -444,7 +445,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
priority_queue(const _Compare& __x = _Compare(),
_Sequence&& __s = _Sequence())
: c(std::move(__s)), comp(__x)
- { std::make_heap(c.begin(), c.end(), comp); }
+ {
+ std::cout << "hacked" << std::endl;
+ std::make_heap(c.begin(), c.end(), comp);
+ }
template<typename _Alloc, typename _Requires = _Uses<_Alloc>>
explicit
Then rebuild and re-install just libstdc++ to save a lot of time:
cd gcc/build/x86_64-pc-linux-gnu/libstdc++-v3
make -j`nproc`
make install
and now the next build and run:
gcc/build/install/bin/g++ -g -std=c++11 -O0 -o a.out ./a.cpp
./a.out
outputs:
hacked
Tested on Ubuntu 16.04.
Ubuntu 22.04, GCC 12.1
We need to either:
- add
--disable-multilibto./configure - (untested)
sudo apt install gcc-multilib g++-multilib, these are linked to support for 32-bit executables: How to Compile 32-bit Apps on 64-bit Ubuntu?
or else it fails with:
configure: WARNING: using in-tree isl, disabling version check
*** This configuration is not supported in the following subdirectories:
gnattools gotools target-libada target-libphobos target-zlib target-libbacktrace target-libgfortran target-libgo target-libffi target-libobjc target-liboffloadmic
(Any other directories should still work fine.)
checking for default BUILD_CONFIG... bootstrap-debug
checking for --enable-vtable-verify... no
/usr/bin/ld: cannot find Scrt1.o: No such file or directory
/usr/bin/ld: cannot find crti.o: No such file or directory
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/11/libgcc.a when searching for -lgcc
/usr/bin/ld: cannot find -lgcc: No such file or directory
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/11/libgcc.a when searching for -lgcc
/usr/bin/ld: cannot find -lgcc: No such file or directory
collect2: error: ld returned 1 exit status
configure: error: I suspect your system does not have 32-bit development libraries (libc and headers). If you have them, rerun configure with --enable-multilib. If you do not have them, and want to build a 64-bi
t-only compiler, rerun configure with --disable-multilib.
glibc
As a bonus, if you are also interested in C: Multiple glibc libraries on a single host
Related:
- https://unix.stackexchange.com/questions/657370/how-to-compile-libstdc-with-specific-compiler-option
The simplest way is to extract the package source code somewhere: go to an appropriate directory, then run
apt source glibc
In gdb, add the corresponding directory to the source path by using the directory command.
You may also want the detached debug symbols; I don’t know whether Devuan provides debug symbol packages in general (dbgsym packages), but I see it ships libc6-dbg which has the same purpose:
sudo apt install libc6-dbg
Here’s an example gdb session:
$ gdb ls
...
(gdb) directory ~/Debian/glibc
Source directories searched: /home/steve/Debian/glibc:$cdir:$cwd
(gdb) break malloc
Breakpoint 1 at 0x46c8
(gdb) run
Starting program: /bin/ls
Breakpoint 1, malloc (n=1441) at dl-minimal.c:50
50 if (alloc_end == 0)
Some further indications for Ubuntu 22.04 beyond what Stephen said.
To get debug symbols and source, some setup is needed as in:
# Get debug symbols.
printf "deb http://ddebs.ubuntu.com %s main restricted universe multiverse\n" $(lsb_release -cs){,-updates,-security,-proposed} | \
sudo tee -a /etc/apt/sources.list.d/ddebs.list
sudo apt install ubuntu-dbgsym-keyring
sudo apt update
sudo apt install coreutils-dbgsym
# Get source as per: https://askubuntu.com/questions/496549/error-you-must-put-some-source-uris-in-your-sources-list
# Produces directory "coreutils-8.32"
sudo cp /etc/apt/sources.list /etc/apt/sources.list~
sudo sed -Ei 's/^# deb-src /deb-src /'
/etc/apt/sources.list sudo apt-get update
apt source coreutils
Then, to get GDB to actually find the sources, you might need to either cd into the downloaded source, or play with stuff like:
set substitute-path . glibc-2.35
as mentioned at: https://askubuntu.com/questions/487222/how-to-install-debug-symbols-for-installed-packages/1434174#1434174