Strange behavior with gdb printf - gdb

I have a issue with gdb printf in version 9.1
echo -e '#include<stdio.h> \n int main(){ \n printf("Hello"); \n }' > test.c
gcc -g test.c -o test
echo 'break test.c:4' > test.gdb
echo 'run' >> test.gdb
echo 'set $aux = (char*)malloc(256)' >> test.gdb
echo 'set $e = strcpy($aux, "abc")' >> test.gdb
echo 'printf "%s", $aux' >> test.gdb
gdb --batch --command=test.gdb test
Output with gdb 9.1:
Breakpoint 1 at 0x1167: file test.c, line 4.
Breakpoint 1, main () at test.c:4
4 }
�e���
Expected output (same as gdb v8):
Breakpoint 1 at 0x1167: file test.c, line 4.
Breakpoint 1, main () at test.c:4
4 }
abc
I've checked charset, but it seems ok.
Any idea about that?

This is Bug 25650 - GDB can't 'printf' a convenience variable holding an inferior address, fixed in gdb 9.2.
If you can't upgrade to gdb 9.2 but can recompile your existing distro's gdb 9.1, there is a two-line patch.
On Ubuntu 20.04, which comes with gdb 9.1-0ubuntu1:
run apt build-dep gdb to haul in the packages needed to build gdb from source
run apt install dpkg-dev (to get /usr/bin/dpkg-source)
uncomment the deb-src lines in /etc/apt/sources.list
run apt update
cd to an empty directory and run apt source gdb . Doing this in a fresh new directory will make it easier to clean things up after the compilation.
cd to gdb-9.1 and apply the patch to gdb/printcmd.c
build and install gdb. For example, to put it in /usr/local/bin, the default, you'd run
mkdir build
cd build
../configure
make
make install

Related

Removing OpenSSL 3.0 devel so C++ compiles on Linux

I'm on Ubuntu 22.04 and compiling this C++ Github pull request:
https://github.com/ftexchange/ftx/pull/13
However, the PR contains a compile error.
Somebody posted to fix the error OpenSSL 3.0 devel version must be "removed":
It seems like the compiler was using OpenSSL 3.0 devel version, I had
to remove that
How do I achieve this?
This is what I did on Ubuntu 22.04 LTS.
$ sudo apt install libboost-dev libssl-dev
$ git clone --recursive --branch openssl-1.1 https://github.com/arf-labs-ou/ftx.git
$ cmake -G Ninja -S ftx/cpp -B build -DCMAKE_BUILD_TYPE=Release
$ cmake --build build
Trying to build at this point will trip deprecation warnings when compiling against the system OpenSSL 3. But because ftx has done the extremely inadvisable thing of hard-coding -Werror in their build, this is promoted to a spurious error. Deprecated doesn't mean "won't work today"; it means "upstream must fix". You are not upstream, so this ought not affect you, but, alas, low-quality build code is not a great surprise.
We will hack around this by wrapping the compiler with a shell script that deletes warning flags from the command line. Create a file called no-warnings.sh:
#!/bin/bash
ARGS=()
for arg in "$#"; do
if [[ ! "$arg" =~ ^-W ]]; then
ARGS+=("$arg")
fi
done
"${ARGS[#]}"
Now let's inject it into the build via the CMAKE_CXX_COMPILER_LAUNCHER hook:
$ chmod +x no-warnings.sh
$ rm -rf build
$ cmake -G Ninja -S ftx/cpp/ -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER_LAUNCHER=$PWD/no-warnings.sh
$ cmake --build build/
This should work but, unfortunately, even this wasn't enough to build successfully. The code itself has a type error! I wonder if something changed between Boost 1.71 and 1.74. Anyway, I applied the following patch:
diff --git a/cpp/src/util/HTTP.cc b/cpp/src/util/HTTP.cc
index 30e0277..2d043f2 100644
--- a/cpp/src/util/HTTP.cc
+++ b/cpp/src/util/HTTP.cc
## -100,8 +100,8 ## void HTTPSession::authenticate(http::request<http::string_body>& req)
std::string path(req.target());
std::string body(req.body());
- long ts = get_ms_timestamp(current_time()).count();
- std::string data = std::to_string(ts) + method + path;
+ auto ts = std::to_string(get_ms_timestamp(current_time()).count());
+ std::string data = ts + method + path;
if (!body.empty()) {
data += body;
}
And now the above commands produce a successful build. The example programs run and produce reasonable output, as well.

LLDB is not launching a Clang++ compiled program

I am tying to launch a debugging of clang code via lldb. I'm using a WSL Ubuntu 20.04 LTS. I installed a clang and lldb via sudo apt-get install clang and sudo apt-get install lldb accordingly.
The test code (mytest.cpp) is the following:
#include <iostream>
int main()
{
std::cout << "TEST" << std::endl;
return 0;
}
Compilation command: clang++ -g -std=c++17 -o mytest mytest.cpp
Then I calling a debugger:
lldb mytest
(lldb) target create "mytest"
Current executable set to '/home/adzol/Projects/mytest' (x86_64).
(lldb) r
Process 51 launched: '/home/adzol/Projects/mytest' (x86_64)
And that's it. Nothing is happening. What can be wrong here?
But if I am calling my executable file directly, I am getting expected console output:
./mytest
TEST
I found out that the problem was is WSL 1. I updated my WSL to WSL 2 and this all works.

how to hold xterm during debugging an mpi program?

I run the debugger via
mpirun -n 4 xterm -e gdb -x commands.gdb ./my_mpi_programm
where the file "commands.gdb" just contains the commands
start
continue
The problem is that my 4 xterm immediately close before I get a chance to inspect the error message or do any debugging.
I'm using the latest ubuntu distribution. However, on my friend's old Suse-distribution, xterm is held open.
How can I force the xterms to stay?
EDIT: the "-hold" option doesnt work as well as
mpirun -n 4 xterm -e "gdb -x commands.gdb ./my_mpi_programm;bash"
Try
mpirun -n 4 xterm -e bash -c 'gdb -x commands.gdb ./my_mpi_programm; sleep 60'

How to GDB step debug a dynamically linked executable in QEMU user mode?

For example for ARM, if I compile statically, all works fine:
sudo apt-get install gdb-multiarch gcc-arm-linux-gnueabihf qemu-user
printf '
#include <stdio.h>
#include <stdlib.h>
int main() {
puts("hello world");
return EXIT_SUCCESS;
}
' > hello_world.c
arm-linux-gnueabihf-gcc -ggdb3 -static -o hello_world hello_world.c
qemu-arm -L /usr/arm-linux-gnueabihf -g 1234 ./hello_world
On another terminal:
gdb-multiarch -q --nh \
-ex 'set architecture arm' \
-ex 'set sysroot /usr/arm-linux-gnueabihf' \
-ex 'file hello_world' \
-ex 'target remote localhost:1234' \
-ex 'break main' \
-ex continue \
;
This leaves me at main, and I can see the source and step debug as usual.
However, if I remove the -static, and keep everything else unchanged, my breakpoint never gets hit, and the program runs until completion:
The target architecture is assumed to be arm
Reading symbols from hello_world...done.
Remote debugging using localhost:1234
Reading symbols from /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3...(no debugging symbols found)...done.
0xff7b3b80 in ?? () from /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3
Breakpoint 1 at 0x50c: file hello_world.c, line 5.
Continuing.
[Inferior 1 (Remote target) exited normally]
The executable itself does work fine however:
qemu-arm -L /usr/arm-linux-gnueabihf ./hello_world
prints:
hello world
I have seen: How to single step ARM assembler in GDB on Qemu? but it didn't cover the case of dynamically linked executables specifically.
Tested on Ubuntu 18.04, gdb-multiarch 8.1-0ubuntu3, gcc-arm-linux-gnueabihf 4:7.3.0-3ubuntu2, qemu-user 1:2.11+dfsg-1ubuntu7.3.
Edit: working pristine crosstool-ng setup
As a sanity check, I tried to get a clean toolchain with crosstool-ng, and it worked:
git clone https://github.com/crosstool-ng/crosstool-ng
cd crosstool-ng
git checkout d5900debd397b8909d9cafeb9a1093fb7a5dc6e6
export CT_PREFIX="$(pwd)/.build/ct_prefix"
./bootstrap
./configure --enable-local
./ct-ng arm-cortex_a15-linux-gnueabihf
# Has to be older than host kernel, which is 4.15.
printf "
CT_LINUX_V_4_14=y
CT_LINUX_VERSION=\"4.14.0\"
" >> .config
./ct-ng oldconfig
env -u LD_LIBRARY_PATH time ./ct-ng build -j`nproc`
cd ..
crosstool-ng/.build/ct_prefix/arm-cortex_a15-linux-gnueabihf/bin/arm-cortex_a15-linux-gnueabihf-gcc -ggdb3 -o hello_world hello_world.c -ggdb3 -static -o hello_world hello_world.c
qemu-arm -L crosstool-ng/.build/ct_prefix/arm-cortex_a15-linux-gnueabihf/arm-cortex_a15-linux-gnueabihf/sysroot -g 1234 ./hello_world
And on another shell:
./.build/ct_prefix/arm-cortex_a15-linux-gnueabihf/bin/arm-cortex_a15-linux-gnueabihf-gdb \
-q --nh \
-ex 'set architecture arm' \
-ex 'set sysroot crosstool-ng/.build/ct_prefix/arm-cortex_a15-linux-gnueabihf/arm-cortex_a15-linux-gnueabihf/sysroot' \
-ex 'file hello_world' \
-ex 'target remote localhost:1234' \
-ex 'break main' \
-ex continue \
;
And it also works with the distro provided gdb-multiarch.
The failure is due to -pie -fpie, and there is a bug report for it at: https://bugs.launchpad.net/qemu/+bug/1528239
Explicitly setting -no-pie -fno-pie makes it work on both crosstool-ng and Ubuntu host.
The difference is that the Ubuntu one has GCC built to use -fpie by default, while my crosstool-ng build did not.
This can be checked with:
gcc -v
which on the host GCC contains:
--enable-default-pie
but not in the crosstool-ng build.
How I found this out: the other day I was playing around with -fpie and I noticed that the .text addresses were really small in that case: What is the -fPIE option for position-independent executables in gcc and ld?
Then I saw that the break address was very small with the packaged toolchain, and made the link.

How to build nodejs as a shared library from source code

I need to include node.h in my c++ project, I tried to build node from source code using:
./configure
sudo make
I got a node executable and some object files and .a files, I need to build as .so file to use it in my c++ code.
I tried to build libnode, but I got cmakelists error and this is not official nodejs project.
if anybody know how to build nodejs from source code as .so file will be great, a similar question in a google group but the answer is not working.
Support for building as a shared library has been added in to node mainline. Please see PR 6994 and specifically this comment.
I just ran
git clone https://github.com/nodejs/node.git
cd node
git checkout v6.9.4
./configure --shared
make -j4
which produced:
ubuntu#server:~/node$ find . -name libnode.so\* -exec ls -la {} \;
-rwxrwxr-x 2 ubuntu ubuntu 31576776 Jan 6 18:57 ./out/Release/lib.target/libnode.so.48
-rw-rw-r-- 1 ubuntu ubuntu 387 Jan 6 18:57 ./out/Release/.deps/home/ubuntu/node/out/Release/lib.target/libnode.so.48.d
-rw-rw-r-- 1 ubuntu ubuntu 4202 Jan 6 18:57 ./out/Release/.deps/home/ubuntu/node/out/Release/obj.target/libnode.so.48.d
-rwxrwxr-x 2 ubuntu ubuntu 31576776 Jan 6 18:57 ./out/Release/obj.target/libnode.so.48
ubuntu#server:~/node$
I think it is easier to build in a static library as shared requires the addition of '-fpic'.
For my projects (under Linux) I use this script to built a static node.js library:
#!/bin/sh
# This script is LGPL feel free to use it!
if test ! "$#" = "1"; then
echo "Run with the archive in parameter:"
echo "\t${0} ./node-v0.XX.XX.tar.gz"
echo "\nIt will build a ./libnode_static.a in current dir"
return
fi
HERE=$PWD
#Extract Tarball
tar xf $1 | exit 1
DIRNAME=`echo $1 | sed s/.tar.gz//g`
cd $DIRNAME
#Patch node.gyp to build in static
sed -i "s/'type': 'executable',/'type': 'static_library',/g" ./node.gyp
#Patch node_main.cc to rename the main in node_main
sed -i "s/int main(/int node_main(/g" ./src/node_main.cc
#Build Node.js
./configure
make -j8
#Move to build directory
cd ./out/Release
#Extract .a
#Cleanup if previous build
rm -fr *.tmpd
echo "== Extracting *.a =="
#Make sure we create a directory
#for each.a as some .o might
#have the same name
for a in `ls *.a`
do
echo "\t${a}..."
mkdir "$a.tmpd"
cd "$a.tmpd"
ar x ../$a
cd ..
done
#Repack in a single .a
find . -iname "*.o" | xargs ar rcs libnode_static.a
#Cleanup
rm -fr *.tmpd
echo "== DONE =="
#Move in start directory
mv ./libnode_static.a ${HERE}/
cd ${HERE}
#Sanity CHECK
echo "== Performing Sanity Check =="
TMP_FILE=`mktemp /tmp/XXXXXX.cxx`
TMP_EXE=`mktemp /tmp/XXXXXX`
cat << . > ${TMP_FILE}
int node_main( int argc, char **argv);
int main(int argc, char ** argv )
{
node_main( argc, argv );
return 0;
}
.
#Try compiling
g++ ${TMP_FILE} -o ${TMP_EXE} -lnode_static -ldl -pthread -L.
#Try running
RET=`${TMP_EXE} -e "console.log('okfromnode')"`
if test "x${RET}" = "xokfromnode"; then
echo "== Sanity check OK =="
else
echo "== Sanity check FAILED =="
exit 1
fi
rm ${TMP_FILE} ${TMP_EXE}
echo "== Node.js is now built statically in ./libnode_static.a =="
exit 0
Run it as follows :
sh script.sh node-v0.10.XX.tar.gz
If everything goes well you should get a libnode_static.a in current directory.
Use it with a code like this:
int node_main( int argc, char **argv);
int main(int argc, char ** argv )
{
/* Here we spawn a node.js instance */
return node_main( argc, argv );
}
And compile like this:
g++ ./test.cxx -o ./my_node -lnode_static -ldl -pthread -L.
And you have embedded node :
./my_node -e "console.log('Hello World')"
#Outputs
Hello World
Hope this helps.
This is how i did it in windows. Except for the build procedures, everything should be same.
Nodejs uses node-gyp for building. You can read this for building and installation. Or just git clone the repository.
Open node.gyp in the node-vX.XX.XX and find
'targets': [
{
'target_name': 'node',
'type': 'executable',
change the executable to shared_library.
Run vcbuild.bat in windows or for other platforms follow instructions.
Update:
https://gist.github.com/aklen/849f3460b7a028c9aed8a84e1d4cecb7
Windows
.\vcbuild release vs2017 dll x64
.\vcbuild release vs2017 dll x86
.\vcbuild debug vs2017 dll x64
.\vcbuild debug vs2017 dll x86
Linux / MacOS
./configure --shared --release
make -j4
./configure --shared --debug
make -j4
Other build options
https://github.com/nodejs/node/blob/master/BUILDING.md