I want to get a detailed look at what's going on both before and after main()
using GDB. Would it be enough just to recompile glibc with -g
and link against that?
相关问题
- Multiple sockets for clients to connect to
- How to compile C++ code in GDB?
- What is the best way to do a search in a large fil
- glDrawElements only draws half a quad
- Pass custom debug information to Microsoft bot fra
if you want to play with the debugger, you can use GDB this way:
(it's
/usr/lib/debug/lib64/libc-2.14.so.debug
in my system)You don't need to start in the debugger.
When the OS loads your executable, it passes control to its entry point which is not the function named
main()
. In GCC and glibc, the true entry point is usually named_start
, but your mileage can vary depending on your platform. Of course, if you aren't using glibc, or are using a different C compiler, then it can vary even more.The key job of the code at
_start
is to initialize the everything that is required in order to create the conditions thatmain()
expects. Note that this is much more complex for C++, and since GCC supports both languages, the true startup code will have extra features whose sole purpose is to support the requirements of C++.Source code for the
_start
is almost always written in assembler, and is highly platform-specific. For the 32-bit x86 platform, one sample can be found in the glibc source tree, undersysdeps/i386/elf/start.S
.Although it is likely true that you will never need to see this to debug ordinary code on desktop operating systems, a good understanding of how the runtime environment is initialized is often needed when working on small embedded systems. In particular, many embedded systems boot directly from system reset into a version of this startup code. On such a system, it isn't unusual to have to turn on the memory that will be used or correctly configure the CPU's main clock sources and set the first stack pointer to something sensible before it is possible to worry about higher level concepts like the
.text
,.data
and.bss
segments.The version of
start.S
linked to assumes that it is being launched under some flavor of unix or linux (I didn't look too carefully). So it gets to assume that the process has been created and that the code and data segments are already loaded and ready to use. It converts the command line parameters from the format supplied by the OS to the familiararvc
andargv[]
needed to callmain()
, which it does but via a wrapper supplied somewhere else in the glibc sources named__libc_start_main()
found incsu/libc-start.c
.The source to that function is made to appear hugely complex by the abundance of condition complilation directives that support a wide range of features. But in essence, it boils down to something like the following for a common case:
I've left out some details in that sketch, but the outline should be mostly true. The funny business with function pointers named
init
andfini
is primarily to support constructors and destructors of global objects in a C++ program. For plain C linkage, these pointers will be NULL, and there will be no effect.