How to access environment variables inside .gdbinit and inside gdb itself? - linux

I am looking to set up the path for the source code when debugging with gdb. I chose to do that with a .gdbinit file.
Basically, it contains a command:
directory="/path/to/src".
However, I would like to be able to specify that command as:
directory="$SOURCESROOT/src"
where SOURCESROOT is an environment variable. And, if possible, being able to do that inside gdb debuuging session too, by entering directory=$SOURCESROOT/folder.
Basically, I am looking to access inside gdb (or inside .gdbinit) the environment variables.
But not the environment of the debugee (set env and so on), but the environment of the gdb itself (ie. of the bash prompt where I type in the first place "gdb program").
While typing shell $SOURCESROOT inside gdb session shows the content of the environment variable, this is quite useless, as I cannot enter: directory=shell $SOURCESROOT.
PS: Anybody found an ideal setup for Linux (Debian) to download the sources with "apt-get source", to update those with some kind of "apt-get update" utopic command and to install them so that gdb will automatically find these sources?

Nevermind, I found how to do it by using Python scripting.
My .gdbinit file is now:
python
import os
gdb.execute('directory' + os.environ['SOURCES'] + '/package_name/src')
end
show directories

(6 year late!)
Don't use .gdbinit for this purpose. It does not expand env vars. Instead, use this commandline to launch gdb:
gdb --init-eval-command="set dir $SOURCESROOT/src"
(gdb) show dir
/path/to/src
FYI this technique can be used to set other critical variables, e.g
gdb --eval-command="set sysroot $SYSROOTDIR"
Which sets sysroot and solib-absolute-prefix in gdb

If you don't want to involve python, then this could work?
"show environment [varname]
Print the value of environment variable varname to be given to your program when it starts. If you do not supply varname, print the names and values of all environment variables to be given to your program. You can abbreviate environment as env."
ftp://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_19.html
Maybe they could be used for conditions as well:
https://www.adacore.com/gems/gem-119-gdb-scripting-part-1

In my case I'd like to set global history in common $HOME/.gdbinit, so I used
set history filename ~/.gdb_history
instead of
set history filename $HOME/.gdb_history

Related

can not set linux environment variables as I expect

I open two terminals.
In first terminal:
export CLASSPATH="abc"
printenv CLASSPATH ---> output is abc
then in second terminal:
printenv CLASSPATH ---> no output
why in second terminal I dont have the variable?
It's not going to work because each program inherits environment, that
is a list of environment variables and their values from their parent
process. Environment is not automatically propagated to all other
programs on the system but is only inherited by children of the given
program. To set a global environment that would work in all newly
opened terminals you need set it in the file that is sourced each time
you open the terminal. What file would that be depends on what shell
you use and your system local setup. For example, if you use bash you
should put export CLASSPATH="abc" in ~/.bashrc.
For accessing global variable you need to put $ before it. Are you doing that?
try echo $CLASSPATH
I think you will find this helpful.

Android Studio - cmake - access environement variable?

This question is specific to using cmake as part of Android Studio build process.
I'm using Android Studio 2.2 preview 7 on linux (ubuntu)
Inside the CMakeLists.txt I am able to access the Android NDK path using: ${ANDROID_NDK}
But how can I access:
Any environment variable ?
If not possible, at least the Android SDK path ?
I already tried to used $ENV{name_of_the_environment_variable_here} but it's always empty, even if the environment variable exist. I guess that when gradle invoke cmake it "hide" the env var somehow.
I don't think you can use $ENV, it's just an example of a variable because they're environment variables. However, you should be able to type env and hit enter for a list of the variables you currently have set. Then, the ones you see in the list, you can invoke by typing $VARIABLE_NAME, using a command before them to get them to do something. E.g. echo $VARIABLE will echo your variable to stdout.
I'm not sure how $ANDROID_SDK was set, if it was part of an install process, etc. but generally you would set user environment variables in .profile, .bash_profile or .bashrc configuration files. These files are read by the shell in that order. System-wide variables are set in /etc/environment, /etc/profile, and /etc/bash.bashrc, but you probably don't want to mess with those (most distros encourage making ancillary additions in /etc/profile.local, but that's a story for another answer).
It doesn't particularly matter which one of these files you use, unless what you're trying to do interacts with the order in which they are loaded. Generally, I look for where the variables have been set by either the OS or other stuff I've added and put them near those. You can find where environment variables are set by typing:
% for i in .profile .bash_profile .bashrc; do grep -H PATH $HOME/$i; done
(% is the prompt, don't type %)
.. and this will loop through the 3 files and show you if a user $PATH is set in any of them.
Bash uses the export ENV command as opposed to set ENV, which is from the original sh, which AFAIK is only default on FreeBSD and derivatives like pfSense anymore. Almost all other OS use Bash by default, except MacOS which recently moved to zsh and also uses export, and OpenBSD which uses ksh (nobody uses OpenBSD).
If you want to verify which shell you are using, type echo $SHELL, or echo $0 and hit enter, and it should let you know.
You can add the environment variable ephemerally by typing this command in your bash terminal and pressing enter:
% export ANDROID_SDK_ROOT=/home/username/AndroidSDK
To be clear, this is an example path, so it'd be best to use the actual path in which your android SDK files reside. However, this example was a default install location Android Studio tried to use when I installed it recently, so if you're not sure where they are, it's probably a good place to check.
To have a more permanent setting of your environment variable, open a text editor and add the line above to one of the configuration files I mentioned in the first paragraph (they'll be in your $HOME folder). Or, you can run this from the prompt and it'll add it to your file automatically:
% echo 'export ANDROID_SDK_ROOT=/home/username/AndroidSDK' >> $HOME/.bashrc
Take care to use two angle brackets and not one, as one angle bracket will overwrite the entire file with the single line.
How can I access Any environment variable ?
If you're not sure which folder is $HOME, try typing cd $HOME and hitting enter - that'll take you there. That's how you access environment variables - use a command with the invocation of the variable and it should act as if you had typed out the entire thing.
To access environment variables, type echo $NAME_OF_VARIABLE and it should echo it to the screen. If you want to search your three config files I mentioned in the beginning for where an environment variable is set, you can use grep as I did earlier, just changing the search string for whatever you're looking for. E.g. (while in $HOME):
% grep SDK_ROOT .bashrc .profile .bash_profile
Or you can type env to list all the currently set variables and filter them by piping the output to the grep command:
% env | grep SDK
If you want to just list all of the set variables and root around the entire thing, just type env instead of piping it to grep (grep's a filter).
Lastly, I'll give you an example of my $ANDROID_SDK_ROOT $ANDROID_SDK and $SDK_ROOT variables in my .bashrc - I noticed while installing these tools, they use all three (isn't that fun?):
% grep ANDROID .bashrc
export ANDROID_SDK=$HOME/development/Android/SDK
export ANDROID_SDK_ROOT=$HOME/development/Android/SDK
export PATH=$PATH:$ANDROID_SDK:$JAVA_HOME:$ANDROID_SDK/cmdline-tools/latest/bin:$ANDROID_SDK/build-tools/32.0.0:$ANDROID_SDK/emulator:$ANDROID_SDK/emulator/bin64:$ANDROID_SDK/tools:$ANDROID_SDK/tools/bin:$ANDROID_SDK/extras:$ANDROID_SDK/platform-tools:$HOME/development/AndroidStudio/bin
export ANDROID_STUDIO=$HOME/development/AndroidStudio
% grep SDK_ROOT .bashrc
export SDK_ROOT=$HOME/development/Android/SDK
export ANDROID_SDK_ROOT=$HOME/development/Android/SDK
Hope that answers some questions, sorry it took so long to give you a response.

How can I print include path in cygwin?

I am new to cygwin & I want to print the list of include paths cygwin will search for header files.
Is there a cygwin bash shell command to print the include path list?
if so, what it is ?
if there is n't any, how can I know the include path list cygwin will search for?
echo $PATH (echo ${PATH}) would be one possibility. To show all environment variables type env.
Normally, include paths are defined by the Make-Environment, either in the makefile, along with the compiler call or within the cmake environment. This is better than to put it in the PATH environment because if someone compiles something different, the "old" include definition in the PATH environment variable maybe in the way (which is not, if you specify it for every project, e.g. in the Makefile or threw the cmake environment).
If someone still wants to define it in the PATH variable, it can be done on the command prompt (if your cygwin(64) resides on "cygdrive/c":
export PATH=/cygdrive/c/cygwin64/usr/include:$PATH

How to actually change/set environment variables from within emacs

In my shell I did: export BLA=foo and then I do echo $BLA and I see foo as expected. I then load up emacs and do M-! for a shell command and do echo $BLA and it's set to something else, bar. So then I run M-x setenv and give it BLA and foo at the prompts but when i do the echo i still see bar. Why would that be and how can I change it? I am trying to do this for some environment variables under which I want to run M-x compile
setenv will modify the environment for the processes emacs launch after you set the value. Running child processes will not be affected.
Thus, doing a (setenv "FOO" "bar") and then M-x shell (provides you have not a running shell yet) will produce a shell with environment variable "FOO" set to "bar".
Your shell in which you've started the Emacs hands over a copy of its environment to its child process (the Emacs), that's how the value is transmitted from the shell to the Emacs. Any change the Emacs then performs with its inherited environment will only affect the Emacs process's environment. There is no way the Emacs's environment can influence the environment of the shell.
If you need to hand information back to the shell, you have to use different techniques like temp files, named pipes, sockets, …
If you just want to check the environment of the Emacs itself, use M-x getenv to look at variables, or use M-! echo $BLA. If this also is showing sth else, then you probably have a special BLA which is automatically set to sth after each command, or which isn't writable at all like RANDOM or similar.

Can a makefile update the calling environment?

Is it possible to update the environment from a makefile? I want to be able to create a target to set the client environment variables for them. Something like this:
AXIS2_HOME ?= /usr/local/axis2-1.4.1
JAVA_HOME ?= /usr/java/latest
CLASSPATH := foo foo
setenv:
export AXIS2_HOME
export JAVA_HOME
export CLASSPATH
So that the client can simply do:
make setenv all
java MainClass
and have it work without them needing to set the classpath for the java execution themselves.
Or am I looking to do this the wrong way and there is a better way?
No, you can't update the environment in the calling process this way. In general, a subprocess cannot modify the environment of the parent process. One notable exception is batch files on Windows, when run from a cmd shell. Based on the example you show, I guess you are not running on Windows though.
Usually, what you're trying to accomplish is done with a shell script that sets up the environment and then invokes your intended process. For example, you might write a go.sh script like this:
!#/bin/sh
AXIS2_HOME=/usr/local/axix2-1.4.1
JAVA_HOME=/usr/java/latest
CLASSPATH=foo foo
export AXIS2_HOME
export JAVA_HOME
export CLASSPATH
java MainClass
Make go.sh executable and now you can run your app as ./go.sh. You can make your script more elaborate too, if you like -- for example, you may want to make "MainClass" a parameter to the script rather than hard coding it.
From your question I am assuming you're using the bash shell.
You can place the variable definitions in a shell script, like so:
AXIS2_HOME=/usr/local/axis2-1.4.1
export AXIS2_HOME
#etc
And then source the script into the current environment, with
source <filename>
or just
. <filename>
That executes the script in the current shell (i.e. no child process), so any environment changes the script makes will persist.
The quick answer is yes, however in your code, you would need to define the variables in the setenv: directive. Doing it at the beginning of the Makefile makes it a local variable to the Makefile. I would use LOCAL_... at the top of the file then set it in the setenv: directive with VAR=LOCAL_VAR etc... Also remember that you will need to call the makefile with make setenv only. I would really look into doing this in a bash script as the variable needs to be created outside of the Makefile. Once the variable has been generated in the environment, you should be able to assign and export from the Makefile.

Resources