I'm trying to debug libc on Ubuntu 14.04 but unable to do so using gdb as the library and the source are not matching correctly.
gdb is unable to place the break point correctly. As in, I'm able to step into a function and see the source code but the break point marker would be at some random place inside the function instead of being at the beginning.
When I proceed statement by statement using next on gdb, the marker would keep jumping up and down (Reason being the source file and debug library are not matching correctly.
My glibc version according to ldd is
ldd --version
ldd (Ubuntu EGLIBC 2.19-0ubuntu6.6) 2.19
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
I've downloaded libc sources using the command:
sudo apt-get source libc6
The above would create the following files:
eglibc-2.19
eglibc_2.19-0ubuntu6.6.debian.tar.xz
eglibc_2.19-0ubuntu6.6.dsc
eglibc_2.19.orig.tar.xz
In gdb I'm doing
dir <path-to-libc-source>/nptl (nptl because I'm stepping into pthread_create)
I've tried using both eglibc-2.19 source as well as eglibc_2.19.orig.tar.xz.
I've also tried setting LD_LIBRARY_PATH: export LD_LIBRARY_PATH=/usr/lib/debug
But the above also doesn't help.
Can somebody who has successfully been able to debug libc code share his/her techniques as to how to do it correctly?
Assuming the source code version and the library version are the same....
The root cause of the 'jumping' is due to the compiler optimization often changes the order of the executable code from the order in the source file.
This happens when the code is compiled with any of the optimization parameters.
Related
I have pre-existing code that was written and is running on a Linux machine. I need to add to this code, this new code which depends on a library using VS. I have decided to develop on Visual Studio using WSL (Windows Subsystem for Linux) then taking the executable/out file to my Linux machine and running it there.
The code I am adding myProg.c uses a function Func(double arg) which comes from the library Reallib.lib
I have included the header file
#include "Support_Files/Reallib.h"
In my project property pages, the .lib file is in the Additional Dependencies
Support_Files/Reallib.lib
The declaration in the Reallib.h file:
long Func(double arg)
At build-time, these are the errors I get:
/mnt/c/Users/mitch/Projects/myproject/myproject/myproject/obj/x64/Debug/myProg.c: in function `main':
undefined reference to Func
ld returned 1 exit status
If I'm including my library already, why am I getting this error? Is it because Linux systems don't use .lib files? How can I combine the code written on Windows with code written on Linux?
Researching online doesn't seem to match my similar problem.
I have already tried using GCC for Remote Linux, but a similar error was produced. But neither (WSL or Remote Linux) seem to play nice with combining .lib files with source code written on Linux.
Now, I could add RealFunc.c and that would clear the error up, but I would just get another undefined reference error, and so on and so forth (RealFunc.c has plenty of other dependencies that are taken care of in Reallib.lib)
Configuration properties > General > Platform Toolset
I've also tried developing only on Linux, bringing the .lib file over and updating my makefile to link that, but it wasn't working (I believe because Linux doesn't use .lib)
What should be my route of action? I NEED the code that is in Reallib.lib. Do I need to bite the bullet and essentially recompile all the source code in Reallib.lib? Do I need to just move over to Linux 100% and use VS Code? I like using VS because it makes the compiling and linking options much easier. I am still new to C and Linux.
I am using Visual Studio 2022 17.4.3
WSL Ubuntu (v20.04)
$ gcc --version
gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
There is no proper/native way to use a Windows library .lib in Linux, your only solution is by re-compiling the library for the targeted platform, in this case, is Linux.
Option A
Simply re-compile the library source code in Linux using GCC or Clang to generate the proper .a static library or .so shared library.
Option B
Install a cross compiler in Windows for Linux, you can use Cygwin if you are familiar with it.
I have written a "hello world" C code:
#include<stdio.h>
int main()
{
printf("hello world");
return 0;
}
When running the below command:
gcc main.c -o main
I am getting below error:
main.c: In function ‘main’:
main.c:8:1: internal compiler error: Segmentation fault
}
^
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-7/README.Bugs> for instructions.
Below is the output of lsb_release -a:
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.6 LTS
Release: 18.04
Codename: bionic
gcc version:
gcc (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
How can I resolve this issue?
Edit
I compiled the code with g++:
g++ main.c -o main
and it worked fine with no errors.
Given your GCC version of gcc (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0 this is an Ubuntu problem. Ubuntu 18.04 was released 4 1/2 years ago, and the odds of this being a problem with GCC itself are rather slim. As #thebusybee noted in the comments, this is almost certainly something caused by some problem with the compiler installation.
What you need to do is find out what's wrong with your Ubuntu GCC installation. First, make sure you're not doing something that causes the problem. Environment variables such as LD_PRELOAD (or any of the LD_* envvals) can effect GCC. There's also many other envvals that can.
Since you post that you can't upgrade the OS, that implies you're working in an organization with separate system administrator(s) that control the OS installation. So if GCC's failing is not caused by something you're doing this is really the system administrators' problem to solve. If your organization gives them control of the OS installation, that includes everything that they control and you're unable to change, such as the OS-supplied GCC installation here.
What you can do to keep working:
First, make sure you're not doing something to cause the problem
Check your environment for any LD_* envvals such as LD_PRELOAD. Make sure they're not causing the problem.
Check for other envvals that could effect GCC.
Install a version of GCC somewhere you are allowed to modify,
such as your home directory
Modify your PATH and other necessary envvals to used your local GCC copy
Use your organization's process(es) to create a trouble ticket to have your system administrator(s) investigate and repair your system. If you're not allowed to modify it, it's their problem.
If you have the time, you add something like the -v verbose flag or use GCC's Developer Options such as -freport-bug to try to figure out what's wrong with your system and help your system administrator(s) in solving the real problem here.
I installed the Code::Blocks on a Windows 10 PC using the downloaded binary codeblocks-20.03-setup.exe. I adjusted the settings to point to my Msys2 MinGW compiler C:\msys64\mingw64 and debugger C:\msys64\usr\bin\gdb.exe. I then created a project with the default console app in c using Code::Blocks. It can compile and run using Code::Blocks.
When I debug it it fails. Code::Blocks gives an error:
Cannot open file: /c/GitLab/debugging-c-code/Exercise Files/Ch02/02_01/02_02_ide/main.c
At /c/GitLab/debugging-c-code/Exercise Files/Ch02/02_01/02_02_ide/main.c:6
The main.c file is open in Code::Blocks. I assume the /c/ vs c:\ part is the problem. I have no idea how to resolve the problem for Code::Blocks.
My Setup:
[..]which gcc
gcc is an external : C:\msys64\usr\bin\gcc.exe
[...]gcc --version
gcc (GCC) 9.1.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
[...]which gdb
gdb is an external : C:\msys64\usr\bin\gdb.exe
[...]gdb --version
GNU gdb (GDB) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
I solved the problem ... after reading the comment from HolyBlackCat. Cygwin will mangle paths because it assumes it is inside the Cygwin environment.
Updated my MSYS installation and installed GDB as part of a complete toolchain:
pacman -S mingw-w64-x86_64-toolchain
Now GDB, GCC and Codeblocks are happy with each other and sharing debug information in a way that everybody understands. Now both GDB and GCC reside in C:\msys64\mingw64.
I originally only installed only GCC and then the other parts as I needed them.
Make sure you don't have any special characters (spaces, non ASCII characters) in the paths where CodeBlocks, MinGW-w64 or your source projects are located.
More info on how you can configure CodeBlocks with MinGW-w64 can be found here: https://winlibs.com/#usage-codeblocks
I am using libmicrohttpd 0.9.53 in my project and decided to update it to the latest version (0.9.71). I am cross-compiling for ARM and this is the output of arm-linux-gcc --version:
arm-linux-gcc (4.4.4_09.06.2010) 4.4.4
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
and the output of /lib/arm-linux-gnueabi/libc.so.6:
GNU C Library (Debian GLIBC 2.19-18+deb8u3) stable release version 2.19, by Roland McGrath et al.
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.8.4.
Compiled on a Linux 3.16.7 system on 2016-02-12.
Available extensions:
crypt add-on version 2.1 by Michael Glad and others
GNU Libidn by Simon Josefsson
Native POSIX Threads Library by Ulrich Drepper et al
BIND-8.2.3-T5B
libc ABIs: UNIQUE
For bug reporting instructions, please see:
<http://www.debian.org/Bugs/>.
The compilation is successful, however, I get these errors when linking with the shared library:
arm-linux-gcc -Llib/libmicrohttpd/lib -Wl,-rpath,./lib -o "proj" build/src/proj.o -lpthread -lm -lmicrohttpd
lib/libmicrohttpd/lib/libmicrohttpd.so: undefined reference to `pthread_setname_np#GLIBC_2.12'
lib/libmicrohttpd/lib/libmicrohttpd.so: undefined reference to `clock_gettime#GLIBC_2.17'
collect2: ld returned 1 exit status
make: *** [makefile:191: proj] Error 1
On the target machine, I ran /lib/arm-linux-gnueabi/libc.so.6 | grep clock_gettime:
782: 000e48e4 116 FUNC GLOBAL DEFAULT 12 __clock_gettime##GLIBC_PRIVATE
1625: 000e48e4 116 FUNC WEAK DEFAULT 12 clock_gettime##GLIBC_2.17
And readelf -Ws /lib/arm-linux-gnueabi/libc.so.6 | grep pthread_setname gives no result.
Apparently, the two symbols mentioned in the error have been added between the old and new releases and it seems like my current version of libc does not define them.
Am I completely off track here? Do I have to somehow update libc? Could you please suggest anything that could point me to the right direction?
It looks like your toolchain defaults -Wl,--as-needed. In this case, link order matters even for shared objects.
Try replacing -lpthread -lm -lmicrohttpd with this:
-lm -lmicrohttpd -lpthread
The clock_gettime#GLIBC_2.17 problem requires a rebuild with the version of glibc in your cross-build environment. It seems it was compiled on the target system (which has glibc 2.19, per your question), but it could have been built against any version that has clock_gettime in libc.so.6, starting with glibc 2.17. Your cross-compilation environment has a glibc version prior to that change (so glibc 2.16 or earlier), so it does not recognize the clock_gettime#GLIBC_2.17 symbol version.
I am trying to build a bare metal arm project. I tried the GNU toolchains arm-elf and arm-none-eabi. Executables generated by both toolchains, when converted to intel hex format, runs fine.
I am using the software Proteus for simulation. Proteus supports debugging executables in both elf and coff format.
In my case Proteus accepts the executable generated by arm-elf but its showing error when loading the executable generated by arm-none-eabi. The error message shown by Proteus is:
I just ran the file command in linux with the two executables as argument, one by one.
The results are shown below.
arm-none-eabi output
image: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, not stripped
arm-elf output
image: ELF 32-bit LSB executable, ARM, version 1, statically linked, not stripped
Is there any option to generate Proteus compatible elf file using arm-none-eabi toolchain?
Edit:
Details of my tollchains' versions.
C:\SysGCC\arm-elf\bin>arm-elf-gcc.exe --version
arm-elf-gcc.exe (GCC) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
C:\SysGCC\arm-elf\bin>arm-elf-as.exe --version
GNU assembler (GNU Binutils) 2.22
Copyright 2011 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `arm-elf'.
sreeyesh#ITP-PTLX118:~$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (15:4.9.3+svn227297-1) 4.9.3 20150529 (prerelease)
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
sreeyesh#ITP-PTLX118:~$ arm-none-eabi-as --version
GNU assembler (2.25-10ubuntu1+5build1) 2.25
Copyright (C) 2014 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `arm-none-eabi'.
Thanks in advance.
I finally found out the solution for the issue. I noticed that, in Proteus, there is an option to configure the toolchain and build the source code from Proteus itself.
I just did the following things in Proteus
Selected GNU ARM toolchain from the list of supported compilers
Configured the toolchain path to point to my arm-none-eabi toolchain.
Created a new project with an empty main function.
Built the project.
The build was successful and more interestingly I could debug the generated executable.
Proteus logs the build commands. When I analyzed the logs, I noticed that some extra options were being used by Proteus when invoking arm-none-eabi-gcc. I experimented with those extra options and finally found out that the option -gdwarf-2 plays the key role.
I updated my makefile with this option and it worked fine.
This option simply enables DWARF version 2 format, That's all that I understood from the web search. But why the arm-elf toolchain worked without this option is still a question in my mind. Maybe, this option is enabled in arm-elf by default.
Anyway I am satisfied with this finding as I can proceed with my work now.
Thanks to all those who spared their precious time to help me out. Hope this finding will help people experimenting with Proteus simulation using the GNU ARM toolchain.