Getting address from gdb.Value - python

I'm creating a command for gdb using python integration and trying to get the address of a variable. I've got the value already using:
v = gdb.parse_and_eval("var_name")
But that v can serialise in a number of ways depending on the type. For example if it's a char*, it will be displayed as:
>>> print v
0x7f06a2cfd320 "x"
>>> print v.address
None
Ok, so this doesn't work as expected. I tried first dereferencing, then getting the address, but that gives me back the original value:
>>> print v.dereference().address
0x7f06a2cfd320 "x"
How can I get the address part only? The only way I could find so far looks a bit long:
>>> vptr = gdb.lookup_type("void").pointer()
>>> print v.cast(vptr)
0x7f06a2cfd320
Is there some more direct way?

It isn't totally clear to me what you are asking.
In the first part it sounds like you want the address of the variable "var_name". In this case, you want ".address" as you wrote; however, note that not all variables have addresses. For example the variable could be put into a register by the compiler. Given that this attribute's value is None, I would guess this is what happened. (You can use other gdb commands to find out for sure...)
In the second part, though, it sounds like maybe you want the value of the pointer. You can either just use the value directly (things like + work fine on Value); or you can cast it directly to a Python "long" to get the value as a plain old scalar:
number = long(v)

Related

Passing a Decimal(str(value)) to a dictionary for raw value

I'm needing to pass values to a dictionary as class 'decimal.Decimal', and the following keeps happening:
from decimal import *
transaction_amount = 100.03
transaction_amount = Decimal(str(transaction_amount))
item = {
'transaction_amount': transaction_amount
}
print(item)
Results:
{'transaction_amount': Decimal('100.03')}
How do I attain the raw 100.03 result, rather than Decimal('100.03')?
This is what I want the dictionary to have saved:
{'transaction_amount': 100.03)}
When I do:
print(transaction_amount)
The result is as expected:
100.03
So where am I going wrong?
I don't see any reason why this question should be downvoted.
When you ask python to print an object, it'll print the textual representation of that object.
Here your variable item is a dictionnary, so its representation is as follow:
{ key: value [, repeat]}
If you want the value inside your dictionnary, you would have to go at the specified key like so :
print(item[transaction_amount])
So basically, your code was fine and your use of decimal too, but you weren't testing it the good way. ;) Happens a lot.
Edit:
It's worth noting that, since what you are getting within the dictionnary object is Decimal(100.03), even when printing the value of the key-value pair as I showed previously, you won't get a pure 100.03, but probably Decimal(100.03).
I'll search some documentation as to how to get the string.
Welp apparently no, it should work like a charm.
Edit: I didn't get the question (which has been edited since then) right.
However because of the extended conversation in the comment section, it'll remain here.

How to put values from dictionary to variable

I try to get all values from section in my ini file (via configparser) as a variable:
hue310section = dict(parser.items('HUE_310'))
for keys, value in hue310section.items():
pairs = keys + ' = ' + value
print(pairs)
it gave me partnewfilepath = http://some_site:PORT/about, but I don't know how to import this output as an python variable, that I can use partnewfilepath somewhere in my code. Of course one section will have more values than only one, and I want to change all that in variable. I trying to find solution but I think I miss something because my knowledge about python is not enough yet. I think I need to rebuilt my for statement but don't have a clue how to do it in this particular problem.
My config.ini file looks like:
[HUE_310]
partNewFilePath = ${common:domain}/about
otherValues = something
nextvalue = another something
UPDATE:
I think I need to elaborate more about what I want to achieve. In other part of my code I check version of site I want to process. If the site has, let say version 3.10 I want to get all values from section HUE_310 from my ini file, and use them as python variable. Rest of my code use those variable and if the site version will change I can get values from other section from my ini file and get those values to python variable and use them. I assume that some variables will change from version to version and that's why I want to prepare my code to check this. Also it gives me some freedom to modify some variable if site will change.
I hope it is now more clear.
You don't need a new variable or a for loop, you already have hue310section dict.
You can just use
hue310section['partNewFilePath']
which will be equal to
"http://some_site:PORT/about"
Note that after hue310section = dict(parser.items('HUE_310'))
, otherValues and nextvalue keys will also be defined.
from configobj import ConfigObj
parser_data = ConfigObj(config_path)
current = parser_data['HUE_310'].get('partNewFilePath', 'http://www.default.com')
config_path is path to the file
http://www.default.com is the default value in case that particular key is not found.

replace the strings with variables in python

The following statement works as expected and myreservation object is created.
myreservation = conn.run_instances(amiid, placement='us-east-1a', key_name='n15a',instance_type=my_instance_type,security_groups=['N-1-0-1-AutogenByAWSMP-'])
But the following does not work. I get an error in the script later because myreservation object is not created.
myreservation = ("conn.run_instances('%s', placement='us-east-1a', key_name='n15a',instance_type='%s',security_groups=['%s'])" % (amiid, my_instance_type, my_security_groups))
I need to replace the security group with variable because that will make it easy for me to change it later.
error is:
The security group '%s' does not exist
when I print that statement and run it at python console, it works as expected
And the following does not work either:
myreservation = conn.run_instances('%s', placement='us-east-1a', key_name='nov15a',instance_type='%s',security_groups=['%s']) % (amiid, my_instance_type, my_security_groups)
your second version doesn't work because you put "conn.run_instances" into the string which probably is not what you want. hard to tell from your very small code example but I'd guess:
myreservation = conn.run_instances(amiid, placement='us-east-1a', key_name='n15a',instance_type=my_instance_type,security_groups=[my_security_groups])
is what you are looking for (assuming my_security_groups is correctly set)
edit:
Why does %s does not work?
'%s' works fine if you use it correctly.
in your third example:
myreservation = conn.run_instances('%s', placement='us-east-1a', key_name='nov15a',instance_type='%s',security_groups=['%s']) % (amiid, my_instance_type, my_security_groups)
you try to use a single replacement tuple for three different strings. this does not work, you'd have to replace each string individually. something like this would probably work, but it doesn't really make sense to use string replacements if you're replacing the whole string
myreservation = conn.run_instances('%s'%amiid, placement='us-east-1a', key_name='nov15a',instance_type='%s'%my_instance_type,security_groups=['%s'my_security_groups])

Using Strings to Name Hash Keys?

I'm working through a book called "Head First Programming," and there's a particular part where I'm confused as to why they're doing this.
There doesn't appear to be any reasoning for it, nor any explanation anywhere in the text.
The issue in question is in using multiple-assignment to assign split data from a string into a hash (which doesn't make sense as to why they're using a hash, if you ask me, but that's a separate issue). Here's the example code:
line = "101;Johnny 'wave-boy' Jones;USA;8.32;Fish;21"
s = {}
(s['id'], s['name'], s['country'], s['average'], s['board'], s['age']) = line.split(";")
I understand that this will take the string line and split it up into each named part, but I don't understand why what I think are keys are being named by using a string, when just a few pages prior, they were named like any other variable, without single quotes.
The purpose of the individual parts is to be searched based on an individual element and then printed on screen. For example, being able to search by ID number and then return the entire thing.
The language in question is Python, if that makes any difference. This is rather confusing for me, since I'm trying to learn this stuff on my own.
My personal best guess is that it doesn't make any difference and that it was personal preference on part of the authors, but it bewilders me that they would suddenly change form like that without it having any meaning, and further bothers me that they don't explain it.
EDIT: So I tried printing the id key both with and without single quotes around the name, and it worked perfectly fine, either way. Therefore, I'd have to assume it's a matter of personal preference, but I still would like some info from someone who actually knows what they're doing as to whether it actually makes a difference, in the long run.
EDIT 2: Apparently, it doesn't make any sense as to how my Python interpreter is actually working with what I've given it, so I made a screen capture of it working https://www.youtube.com/watch?v=52GQJEeSwUA
I don't understand why what I think are keys are being named by using a string, when just a few pages prior, they were named like any other variable, without single quotes
The answer is right there. If there's no quote, mydict[s], then s is a variable, and you look up the key in the dict based on what the value of s is.
If it's a string, then you look up literally that key.
So, in your example s[name] won't work as that would try to access the variable name, which is probably not set.
EDIT: So I tried printing the id key both with and without single
quotes around the name, and it worked perfectly fine, either way.
That's just pure luck... There's a built-in function called id:
>>> id
<built-in function id>
Try another name, and you'll see that it won't work.
Actually, as it turns out, for dictionaries (Python's term for hashes) there is a semantic difference between having the quotes there and not.
For example:
s = {}
s['test'] = 1
s['othertest'] = 2
defines a dictionary called s with two keys, 'test' and 'othertest.' However, if I tried to do this instead:
s = {}
s[test] = 1
I'd get a NameError exception, because this would be looking for an undefined variable called test whose value would be used as the key.
If, then, I were to type this into the Python interpreter:
>>> s = {}
>>> s['test'] = 1
>>> s['othertest'] = 2
>>> test = 'othertest'
>>> print s[test]
2
>>> print s['test']
1
you'll see that using test as a key with no quotes uses the value of that variable to look up the associated entry in the dictionary s.
Edit: Now, the REALLY interesting question is why using s[id] gave you what you expected. The keyword "id" is actually a built-in function in Python that gives you a unique id for an object passed as its argument. What in the world the Python interpreter is doing with the expression s[id] is a total mystery to me.
Edit 2: Watching the OP's Youtube video, it's clear that he's staying consistent when assigning and reading the hash about using id or 'id', so there's no issue with the function id as a hash key somehow magically lining up with 'id' as a hash key. That had me kind of worried for a while.

Using a text file to receive a string for a variable in Python, without defining it

I have a text file in which there are several variables. Most of them are used in a Bash script of mine, but I'd like to use the same text file for my Python script. For the lines that are not properly formatted for Python, I want my script to just ignore. For those that are properly formatted, I want the script to check and if it's the variable I'm looking for - use it.
import sys
import re
for ln in open("thefile.txt"):
m = re.match(r"(?P<varname>[^=]*)\s*=\s*(?P<value>.+)", ln)
if m:
varname = m.group("varname")
value_string = m.group("value")
value = eval(value_string)
print value
# so if the variables name is THISVARIABLE, get that value:
if varname == "THISVARIABLE":
mypythonvariable == value
I'm getting the following error:
NameError: name 'Somevariableinmytextfile' is not defined
The Somevariableinmytextfile is the first variable in that file.
My question:
Do I have to define every variable in the txt file, in order to get rid of this error? If not, what shall I do? I'm very new at Python. This is my first program.
The error is eval complaining that the contents of value_string have no meaning as a whatever-it-is.
The real error is using eval at all. (A good post on the pitfalls can be found here.) You don't even need to eval here - leaving value_string as the string the regex gave you will be just fine.
The problem with the present approach
Sample thefile.txt:
foo=bar
baz=42
quux=import os; os.shutdown()
When parsing foo, Python complains that bar isn't defined. (Simple.)
When parsing bar, Python gives you an int instead of a str. (No real problem...)
When parsing quux, Python shuts down your computer. (Uh oh!)
Why you don't need eval
You want a string value, correct? The regex already gives you a string!
varname = m.group("varname")
value = m.group("value")
print value
if varname == "THISVARIABLE":
mypythonvariable = value # You meant = instead of ==?
You get the error because a line in your thefile.txt file:
TEST = ABC
will be evaluated in python as TEST will be assigned to a value of variable ABC but you have no ABC defined.
You could make a dictionary to store your value pairs... this will work with string values:
variables = {}
accepted = ['THISVARIABLE', 'ANOTHERONE']
...
if varname in accepted:
variables[varname]=value
eval throws the error, the value_string's value (which should be a variable) needs to be defined before use.

Categories