2

I have a huge monolith with more than 100 shared libraries. Some of them are so huge that if I let GDB load all the symbols, nearly all my PC RAM is filled up and I can do nothing else. So I want to disable loading all the libraries, and only load the libraries that I need. I accomplish this in two steps:

Disable loading all symbols

set auto-solib-add off

After the application has booted, load only the required libraries

shared /opt/build/Bin/drivers/* 

Now my intention is to automate this using .gdbinit file(which is also loaded by my IDE, QtCreator). However, given the commands are executed during GDB startup, I am not sure how to execute the second command without knowing if the corresponding libraries are loaded. Any help is very appreciated. Thank you.

lightsunray
  • 409
  • 5
  • 16

1 Answers1

1

I am not sure how to execute the second command without knowing if the corresponding libraries are loaded

All dynamically linked libraries should load if you start the program and stop it at the beginning of main. Most of the time it's enough to add start command before shared ... command to load libraries. See also detailed example in this question: How to read and load symbols selectively while attaching a process in gdb?.

It seems that you can't use start command in your home directory init file because symbols are not being read yet and therefore you can't set temporary breakpoint on main. Another option is to create a separate init file in current working directory and place there 3 commands:

set auto-solib-add off
start
shared /opt/build/Bin/drivers/* 

From https://sourceware.org/gdb/current/onlinedocs/gdb/Startup.html#Startup:

  1. Reads the init file (if any) in your home directory and executes all the commands in that file.
  2. Processes command line options and operands.
  3. Reads and executes the commands from init file (if any) in the current working directory

On step 4 the symbols are being read and you can use start command from that moment. But on step 3 the symbols are not read yet and you can't use start command.

ks1322
  • 33,961
  • 14
  • 109
  • 164
  • Thanks for the tip regarding 'start'. Going through its documentation it sounds exactly what I need. I configured my gdbinit as: 'set auto-solib-add off, start, shared mylib'. But after the application has loaded I notice that symbols for my library(mylib) are still not loaded, indicating only the first command taking effect, ignoring the rest. I do not even break at main, as expected by the use of 'start'. What am i doing wrong ? – lightsunray Apr 29 '20 at 07:22
  • You are probably have a stripped binary without any symbols including `main`. Try to set a breakpoint on `main`. Also regex for `shared` command does not look like a regex. It should be like `/opt/build/Bin/drivers/.*`. – ks1322 Apr 29 '20 at 08:17
  • No. As mentioned in the question, I do not have any stripped libraries. This is the exact reason why I started looking for a way not to load all the symbols. Also regarding the regex, it works just fine, when I try 'shared /opt/build/Bin/drivers/*' on the GDB terminal. My only problem is how can I make this all work using GDBInit file. – lightsunray Apr 29 '20 at 09:43
  • Thanks for the reference. I had to set couple of other options for GDB to read the second init file. I eventually break at main, but that still does not load the desired symbols. For that matter, I now believe what I set out to do makes no sense at all. At main none of these libraries are loaded. They are first loaded when the execution comes to the place where these libs loaded in memory. Therefore given this random behavior my best bet is to manually load the desired libraries from the IDE's gdb terminal, after I am sure these libs have been read. Do you agree ? – lightsunray May 04 '20 at 21:29
  • Agree, you can also try to set breakpoint to where these libs are already loaded and load symbols from there. That is substitute `start` with `b ` + `run`. – ks1322 May 05 '20 at 10:00