I am trying to read the value of a static variable in C like:
int variable = value;
The thing is that I only have the binary, and the code with a fake value (it is for a lecture, where we study security aspects of software development).
I have been trying to read the value using the GDB, and
(gdb)info variables
which just gives me a list of the variables (including the one I'm looking for) and what seems to be an address, so I would like to know if there is a way to read the value using GDB?
In GDB, use the 'print' command:
print variable
Voila!
Related
While porting U-Boot on a specific hardware,
a function has to parse a header to get OS entry point to jump into it.
Say, the function get's the os entry point into a global 'C' variable uint32_t osentry.
How to set this value to U-Boot shell command 'go'?
I see U-Boot go (shell) command, has to be set as go $entry
In few examples, I see the entry is fixed address set as shell environment value.
Whereas, for me it is in a global 'C' variable.
How to set a global variable value in C to shell environment variable?
Use the env_set_addr() function to set an environment variable for use as an address from an ordinary program variable.
From include/common.h:
/**
* env_set_addr - Set an environment variable to an address in hex
*
* #varname: Environment variable to set
* #addr: Value to set it to
* #return 0 if ok, 1 on error
*/
ADDENDUM
For some reason, I could n't find this function in the code base I use.
You neglect to mention what version of U-Boot that you are using.
env_set() and its friends were apparently introduced in version 2017.09 to replace setenv() and its friends.
I used similar setenv(), after formatting with sprintf.
Since version 2011.12 the simple setenv() has been augmented with setenv_addr() and/or setenv_hex(), which will convert the unsigned long integer to a string of hex digits for you.
If you are still using a version of U-Boot older than 2011.12, then you will have to do what you describe.
I am beginner with GDB debbuging. I need read variables in GDB, I use the command info variable and get this information:
0x000007c4 variable1.0
0x000007c8 variable2.1
I set a breakpoint inside the variables function and these are defined how type long *. How can I read the value inside these correctly? I tried with show, display, print $variable1, p/x variable and so on commands.
Sorry for my grammar, i am not native speaker.
To view the contents of memory use gdb's x/FMT ADDRESS command e.g. x/d 0x000007c4 (to display an integer sized object from address 0x000007c4 and format it in decimal).
The info variables command in gdb will list all global and static variables and their program addresses. You don't describe the language or implementation you're using, but in C the variable name "variable1.0" is not valid. Therefore it must have been created by some link editor or the compiler in a post-process. Therefore the symbol may not exist in debug information and is only accessible by directly viewing the contents of memory, which is why the gdb p command doesn't work (there is no valid expression to show you that variable because it's not a variable, but just a symbol at an address).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Default values of int when not initialized in c. why do i get different outputs?
Beginner so be lil soft..am compiling a simple code below, I am not assigning any value to my variables but C program generates some random values, why is it so?(Only 2nd variable generates random integers)
So where these values came from?
#include<stdio.h>
main(void) {
int var1;
int var2;
printf("Var1 is %d and Var2 is %d.", var1, var2);
return 0; //Book says I should use this for getting an output but my compiler anyways compile and return me values whether I use it or not
}
//Output 1st compiled: var1 = 19125, var2 = 8983
//Output 2nd compiled: var1 = 19125, var2 = 9207
//Output 2nd compiled: var1 = 19125, var2 = 9127
Your C program is compiled to some executable program. Notice that if you compile on Linux using gcc -Wall, you'll get warnings about uninitialized variables.
The var1 and var2 variables get compiled into using some stack slots, or some registers. These contain some apparently random number, which your program prints. (that number is not really random, it is just unpredictable garbage).
The C language does not mandate the implicit initialization of variables (in contrast with e.g. Java).
In practice, in C I strongly suggest to always explicitly initialize local variables (often, the compiler may be smart enough to even avoid emitting useless initialization).
What you observe is called undefined behavior.
You'll probably observe a different output for var1 if you compiled with a different compiler, or with different optimization flags, or with a different environment (probably typing export SOMEVAR=something before running again your program could change the output for var1, or running your program with a lot of program arguments, etc...).
You could (on Linux) compile with gcc -fverbose-asm -S and add various optimization flags (e.g. -O1 or -O2 ...) your source code yoursource.c and look inside the generated yoursource.s assembler code with some editor.
In C, when you declare variables, that reserves some space for them on the stack. The stack is how C keeps track of which arguments are passed to which function, where variables are stored if you declare them statically within function, where return values are stored, and so on. Each time you call a function, it pushes values on the stack; that is, it writes those values to the next available space on the stack, and updates the stack pointer to account for this. When a function returns, it decrements the stack pointer, to point to where it pointed in the previous function call.
If you declare a variable, but you don't initialize it, you simply get whatever value was in there before. If another function has been called, you may get the arguments passed in to that function; or you might get the return address for the function you are returning to.
In the case that you present, you are showing the main() function, with no other functions called. However, in the process of loading your program, the dynamic linker has probably called several functions within your process space. So the values that you are seeing are probably left over from that.
You cannot depend on what these values are, however. They could be anything; they could be initialized to 0, they could be random data, they could be any sort of internal data.
The content of var1 and var2 are undefined. Thus, they can contain any valid value (depending on many external factors).
It is pure luck that only the second var seams to be random. Try it on another day, after a reboot or after launching a few other programms and I bet the first var will have changed.
It's called local variables . Any local variables have auto storage specifier and these are located on stack in C.
Since you havn't initilaized these varaibles , so it will take any value called garbage value or indeterminate value (Language standard doesn't imposes any requirements that it must have specific value ) so you are getting any random value.
It's purely coincedence that you are getting same value for var1 but not for var2.
But on any other system it might give different values or even on your system may after sometime.
So,Using uninitialized variables is undefined behaviour
In C,
If the variables are declared as Global or static, then they are automatically initialised to zero. But, if they are declared as local , then the values for those variables are indeterminate i.e .., depends on the compiler. (Some garbage value)
is it possible to access variable value through other variable, as below
char var[30];
char buffer[30];
strcpy(buffer, "ABC");
/*variable var is holding the "buffer" variable name as string*/
strcpy(var,"buffer")
is there a way to access the buffer variable value "ABC", through variable var. ?
Not in any practical way in C, and you don't really want to anyway. Tying your program logic to the names of your variables is a horrible idea. Typically I see people attempt this when what they really need is some sort of collection type (and array, a map, whatever).
How about filling us in on the problem you are trying to solve with this?
Per your comment:
I need to have dynamic debug messages, I have a file which contain each function variables that I want to print.
Use stringification in a macro:
#define str(s) #s
int main() {
int bar;
str(bar) /* replaced by "bar" */
}
Not without significant boiler plate code. Variable names are eliminated at compile-time.
In theory, you could store a map from variable names to a pointer to a variable.
No, you can't. If you want indirect access, then declare a pointer and assign var to it.
char *forVar = var;
// Now you can access/modify via [] operator.
You can try using a union
For example:
union example {
char var[40];
char buffer[40];
} e1;
strcpy(e1.var, "ABC");
printf("%s is same as %s", e1.var, e1.buffer);
So basically you want to log some variables when they are written to/read from/passed to functions etc?
Doing this with compiled C is difficult, as mentioned, especially if you are optimising your executable (-0n on the compile statement), in which case some of the variables can disappear completely, or get re-used by other variables.
Using GDB
Having said that, I know gdb can log variable access and that sort of stuff. If you were to write a python script (see http://sourceware.org/gdb/onlinedocs/gdb/Python.html), you should be able to write a script to log variable content.
See this question for more: Do specific action when certain breakpoint hits in gdb
On demand only, using pre-compiler scripting
Alternatively, if you just wanted to do it on demand, you'd be better off using a pre-processing script to add in custom macro's or similar, using a csv file as input:
for each line in CSV:
read variable_name, file_name, variable_type
find all occurrences of variable_name in file_name
for each occurrence
insert printf(....)
On demand only, using macros
Good luck. There isn't a nice way to do it, because you'd generally need some sort of lookup, and you'd need a way of selectively outputting variables to your print function. In some cases you could do something like:
static char _LOGGED_VAR_001 = 'z';
static char _LOGGED_VAR_002 = 'z';
#define cMyVar _LOGGED_VAR_001
#define LOG_ALL_VARS() printf("Vals: %c, %c", _LOGGED_VAR_001, _LOGGED_VAR_002)
void myFunc()
{
char cMyVar; // Gets macro'd to _LOGGED_VAR_001 with LOCAL scope
cMyVar = 'a'; // LOCAL scope _LOGGED_VAR_001 becomes 'a'
LOG_ALL_VARS(); // At this point you print out the LOCAL _LOGGED_VAR_001
// and the global _LOGGED_VAR_002
}
You would get Vals: a, z
This is pretty ugly, would only work for variables with local scope, messes round with memory consumption, could be error prone and is generally a bad idea.
On demand, heap/stack dump
If you have enough storage, you could dump all your memory on demand to a file. This probably wouldn't be very portable, depending on how it was done. I'm not sure how to do it though, in a reliable manner.
Recommendation
Use GDB for design-time diagnostics. It's what it's designed for :)
For (e.g.) analysing released code (automated bug reports), a full dump and then analysis at will might be relevant.
I have one requirement in C.
char abc[]="hello";
char hello[]="world";
Using abc whether we can get the hello variable's value in C.
I know it is possible in some of the languages like Perl, Php, Bash,.,
Is it possible in C?
Yes you are right , this is possible in some other language but not in C ,
since abc is a container which resides in a location (for ex: 1000) and hello is one more
container which resides in another location ( for ex : 2000 ) , so we have no contact between
these two arrays ,
we cannot make a value ( strings ) to point some other value.
so finally THIS IS NOT AT ALL POSSIBLE.
No, this is not possible in C without providing a string lookup table of some sort that could link variables with their names.
It's impossible in C, unlike in more dynamic languages like Perl or Python. However, it's important to keep in mind that even in those languages this isn't recommended. I haven't seen a snippet of code putting this to a good use yet. The eval methods available in dynamic languages are used sparingly, and not for dynamically grabbing variable names.
As soon as the C compiler has figured out where to store the underlying pointers, it forgets about the name you gave it. The dynamic languages solve it with a data structure like a hash map which allows you to store the pointers (value) under a key (the name).
Another option is to read in the debug information. This is only available if you compile your code with -g (gcc) or some other, compiler specific option. Note that the debug format is not standardized, so you'll need to figure out what your compiler uses and how to work with it.
It is not possible in C. It can be done in java by reflection in some cases.
POSIX has several functions that allows you to do it, assuming variable hello is global and isn't static:
void *handle = dlopen(NULL, RTLD_NOW);
// error handling omitted
printf("%s variable contains value %s", abc, (char *)dlsym(handle, abc));
dlsym() return value is casted to char * to suppress warning when using compilers that check format string for printf-alike functions.
And you need to make sure you've specified correct compiler options, e.g. -rdynamic -ldl in case of GCC.