how to pass variables from GDB to invoked python interpeter - python

From some version of GDB (I guess 7 or so) it is possible to invoke python from GDB in interactive or non interactive way.
Here is some example:
(gdb) python print("gdb".capitalize())
Gdb
(gdb)
Is it possible to pass variables from used in GDB into Python? I've tried something like this but with no luck:
Try to pass C variable named c_variable
(gdb) python print(c_variable.capitalize())
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name 'c_variable' is not defined
Error while executing Python code.
Try to pass GDB's variable named $1
(gdb) python print($1.capitalize())
File "<string>", line 1
print($1.capitalize())
^
SyntaxError: invalid syntax
Error while executing Python code.
EDIT
Almost imediatelly after my question I've found this question passing c++ variables to python via gdb
So I've end up with following:
(gdb) whatis p_char
type = char *
(gdb) ptype p_char
type = char *
(gdb) p p_char
$1 = 0x8002004 "hello world"
(gdb) python x=str(gdb.parse_and_eval('p_char')); print(x.split(" "))
['0x8002004', '"hello', 'world"']
This is something that I can work with but I need to do some extra cleanup (remove quotes, address etc), is there any better way? And I still do not know if is possible to pass $1.

Try to pass C variable named c_variable
Try to pass GDB's variable named $1
py print(gdb.parse_and_eval("c_variable"))
py print(gdb.parse_and_eval("$1"))

If you want to work with Python and GDB I would highly recommend reading this. Of special interest to you would be this page that includes parse_and_eval as well as this page on values.
The gdb.parse_and_eval function returns a gdb.Value object. For values that are strings you can use the string method, so:
(gdb) python print(gdb.parse_and_eval("string_var").string())
Hello World
(gdb) python print(gdb.parse_and_eval("string_var").string()[::-1])
dlroW olleH

Related

What is the equivalent of GDB's "define" in PDB?

I use python debugger PDB as a script debugger. I would like to define a PDB function that runs 2 commands at the same time (for instance, print variable value and go to next line). Debugging C code using GDB I would do this:
(gdb) def f
Type commands for definition of "f".
End with a line saying just "end".
>p i
>n
>end
(gdb) f
But trying the same with PDB doesn't work:
(Pdb) def f
*** SyntaxError: invalid syntax
Is there a way to do it?

What does "SyntaxError: Missing parentheses in call to 'print'" mean in Python?

When I try to use a print statement in Python, it gives me this error:
>>> print "Hello, World!"
File "<stdin>", line 1
print "Hello, World!"
^
SyntaxError: Missing parentheses in call to 'print'
What does that mean?
This error message means that you are attempting to use Python 3 to follow an example or run a program that uses the Python 2 print statement:
print "Hello, World!"
The statement above does not work in Python 3. In Python 3 you need to add parentheses around the value to be printed:
print("Hello, World!")
“SyntaxError: Missing parentheses in call to 'print'” is a new error message that was added in Python 3.4.2 primarily to help users that are trying to follow a Python 2 tutorial while running Python 3.
In Python 3, printing values changed from being a distinct statement to being an ordinary function call, so it now needs parentheses:
>>> print("Hello, World!")
Hello, World!
In earlier versions of Python 3, the interpreter just reports a generic syntax error, without providing any useful hints as to what might be going wrong:
>>> print "Hello, World!"
File "<stdin>", line 1
print "Hello, World!"
^
SyntaxError: invalid syntax
As for why print became an ordinary function in Python 3, that didn't relate to the basic form of the statement, but rather to how you did more complicated things like printing multiple items to stderr with a trailing space rather than ending the line.
In Python 2:
>>> import sys
>>> print >> sys.stderr, 1, 2, 3,; print >> sys.stderr, 4, 5, 6
1 2 3 4 5 6
In Python 3:
>>> import sys
>>> print(1, 2, 3, file=sys.stderr, end=" "); print(4, 5, 6, file=sys.stderr)
1 2 3 4 5 6
Starting with the Python 3.6.3 release in September 2017, some error messages related to the Python 2.x print syntax have been updated to recommend their Python 3.x counterparts:
>>> print "Hello!"
File "<stdin>", line 1
print "Hello!"
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print("Hello!")?
Since the "Missing parentheses in call to print" case is a compile time syntax error and hence has access to the raw source code, it's able to include the full text on the rest of the line in the suggested replacement. However, it doesn't currently try to work out the appropriate quotes to place around that expression (that's not impossible, just sufficiently complicated that it hasn't been done).
The TypeError raised for the right shift operator has also been customised:
>>> print >> sys.stderr
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for >>: 'builtin_function_or_method' and '_io.TextIOWrapper'. Did you mean "print(<message>, file=<output_stream>)"?
Since this error is raised when the code runs, rather than when it is compiled, it doesn't have access to the raw source code, and hence uses meta-variables (<message> and <output_stream>) in the suggested replacement expression instead of whatever the user actually typed. Unlike the syntax error case, it's straightforward to place quotes around the Python expression in the custom right shift error message.
Unfortunately, the old xkcd comic isn't completely up to date anymore.
Since Python 3.0 you have to write:
print("Hello, World!")
And someone has still to write that antigravity library :(
There is a change in syntax from Python 2 to Python 3.
In Python 2,
print "Hello, World!"
will work but in Python 3, use parentheses as
print("Hello, World!")
This is equivalent syntax to Scala and near to Java.
Basically, since Python 3.x you need to use print with parenthesis.
Python 2.x: print "Lord of the Rings"
Python 3.x: print("Lord of the Rings")
Explanation
print was a statement in 2.x, but it's a function in 3.x. Now, there are a number of good reasons for this.
With function format of Python 3.x, more flexibility comes when printing multiple items with comma separated.
You can't use argument splatting with a statement. In 3.x if you have a list of items that you want to print with a separator, you can do this:
>>> items = ['foo', 'bar', 'baz']
>>> print(*items, sep='+')
foo+bar+baz
You can't override a statement. If you want to change the behavior of print, you can do that when it's a function but not when it's a statement.
If your code should work in both Python 2 and 3, you can achieve this by loading this at the beginning of your program:
from __future__ import print_function # If code has to work in Python 2 and 3!
Then you can print in the Python 3 way:
print("python")
If you want to print something without creating a new line - you can do this:
for number in range(0, 10):
print(number, end=', ')
In Python 3, you can only print as:
print("STRING")
But in Python 2, the parentheses are not necessary.
I could also just add that I knew everything about the syntax change between Python2.7 and Python3, and my code was correctly written as print("string") and even
print(f"string")...
But after some time of debugging I realized that my bash script was calling python like:
python file_name.py
which had the effect of calling my python script by default using python2.7 which gave the error. So I changed my bash script to:
python3 file_name.py
which of coarse uses python3 to run the script which fixed the error.
print('Hello, World!')
You're using python 3, where you need brackets when printing.
Outside of the direct answers here, one should note the other key difference between python 2 and 3. The official python wiki goes into almost all of the major differences and focuses on when you should use either of the versions. This blog post also does a fine job of explaining the current python universe and the somehow unsolved puzzle of moving to python 3.
As far as I can tell, you are beginning to learn the python language. You should consider the aforementioned articles before you continue down the python 3 route. Not only will you have to change some of your syntax, you will also need to think about which packages will be available to you (an advantage of python 2) and potential optimizations that could be made in your code (an advantage of python 3).
So I was getting this error
from trp import BoundingBox, Document
File "C:\Users\Kshitij Agarwal\AppData\Roaming\Python\Python39\site-packages\trp\__init__.py", line 31
print ip
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(ip)?
This is a Python package error, in which Python2 has been used and you are probably running this on Python3.
One solution could be to convert Python2 print something to Python3 print(something) for every line in each file in the package folder, which is not a good idea😅. I mean, you can do it but still there are better ways.
To perform the same task, there is a package named 2to3 in Python which converts Python2 scripts to Python3 scripts. To install it, execute the 👇 command in terminal..
pip install 2to3
Then change the directory in terminal to the location where the package files are present, in my case - C:\Users\Kshitij Agarwal\AppData\Roaming\Python\Python39\site-packages\trp
Now execute the command 👇
2to3 . -w
and voila, all the Python2 files in that directory will be converted to Python3.
Note:- The above commands hold true for other operating systems as well. Only Python package path will vary as per the system.
print "text" is not the way of printing text in python as this won't work
print("text") will print said text on your screen in the command line

Multiline script in a python command line argument

I am trying to invoke python from within an arch linux PKGBUILD script:
python -c "from module import func; func()"
The func raises an exception, which is expected behavior but causes the script to fail.
Catching the exception like this does not work:
python -c "from module import func; try: func(); except ValueError: pass"
It seems there is no way to put try/except statements into a single line (Python: try statement in a single line).
Is there another way to ignore the exception or the fact that python returns with an error?
A solution that does not require additional scripts or other files would be most welcome :)
Strings in shell can contain embedded newlines:
python -c 'from module import func
try:
func()
except ValueError:
pass
'
Note that this presents a challenge if the Python to run contains a mix of quotation marks, which would require some contortions to ensure they are all escaped properly. In that case, a here document would be more appropriate then the -c option (although this presents its own issues if the code to run needs to read from standard input.)
python << EOF
from module import func
try:
func()
except ValueError:
pass
EOF
You can also enter the script to be executed interactively like this:
$ cat -- | python
<code here>
<code here>
<code here>
<press Ctrl-D>
and Python will run what you entered, for example:
~$ cat -- | python
from module import func
try:
func()
except ValueError:
pass
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named module

How do I execute a function?

I'm new to the python and i was trying to do my first python function, but unfortunately i faced some problems to get the expected result from this simple function please help me to show the output of that function. the below posted function is written in the python editor
i do not know how to call this function from the python shell to show its result.
python code:
def printme( str ):
"This prints a passed string into this function"
print str;
return;
python shell:
>>> printme("d")
>>> Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
printme("d")
NameError: name 'printme' is not defined
$ cd /path/to/your/filename.py
$ python
>>> from filename import printme
>>> printme("hello world!")
You have to load the script as you start the interpreter. From a terminal shell (like bash or zsh):
$ python2 -i script.py
>>> printme("hola")
hola
>>>
On a side note, you don't have to terminate your statements with a semicolon (if they are in their own line), neither have to append a return statement at the end of the function (since indentation and line separation are significative in Python).
If you are using any of the IDEs for python, you could actually run the program in python shell by pressing/typing the Run(F5 equivalent). If that is not the case, read along:
Save the program as test.py (or any other name) in any location of your choice.
Start python shell
>>import sys
>>sys.path
If the directory in which you saved the test.py is present in the output of sys.path, go to step 7
sys.path.append("directory address where you saved the test.py")
>>import test #note .py is removed
>>test.printme("Hello World")
sys.path is the list containing all the directories where python looks for importing modules. By adding (appending) your directory you are ensuring the test.py can be imported as module test. You can then call any functions of test.py as test.fucn()
At step 7 you could have done:
7. >>from test import printme
8. >>printme("Hello again")
If you're using the unix shell:
$ cd C:\yourpath
$ python mypythonfile.py
If you are using the interactive mode, then this:
execfile("C:\\myfolder\\myscript.py")
The long way in interactive mode, but if you prefer to set your default path:
import os
prevPath = os.getcwd() #save the default path
myPath = "C:\myPython\somepath"
os.chdir(myPath) #set your python path
execfile("myscript.py") #executes the file
#os.chdir(prevPath) will restore the default path
Or did i misunderstood your question? If you just want to run a function, it's just as simple as this..
>>> def printme(str):
print str
>>> printme("Hello world!")
Hello world!
>>>
Hope this helps!
My python knowledge is very low... , you question come from this tutorial ,I have all to write as your example on a Linux shell , and i having none problem...
>>> def printme(str):
This print .......................
print str
return
>>> printme('d')
d
how i have Understand , you problem is that you to prove working with idle console and a Linux shell without before your code to save....i think , the examples from shellfly and alKid describe gut , how can you solving your problem...
sorry about my English....

Exiting from python Command Line

To exit from Python command line, I have to type exit(). If I type exit, it says
Use exit() or Ctrl-Z plus Return to exit
Usually when you type exit, you would want to exit the program. Why does the interpreter give me the above error when it knows I am trying to exit the command line? Why doesn't it just exit? I know it doesn't matter and its a silly question but I am curious.
This works for me, best way to come out of python prompt.
exit()
In my python interpreter exit is actually a string and not a function -- 'Use Ctrl-D (i.e. EOF) to exit.'. You can check on your interpreter by entering type(exit)
In active python what is happening is that exit is a function. If you do not call the function it will print out the string representation of the object. This is the default behaviour for any object returned. It's just that the designers thought people might try to type exit to exit the interpreter, so they made the string representation of the exit function a helpful message. You can check this behaviour by typing str(exit) or even print exit.
When you type exit in the command line, it finds the variable with that name and calls __repr__ (or __str__) on it. Usually, you'd get a result like:
<function exit at 0x00B97FB0>
But they decided to redefine that function for the exit object to display a helpful message instead. Whether or not that's a stupid behavior or not, is a subjective question, but one possible reason why it doesn't "just exit" is:
Suppose you're looking at some code in a debugger, for instance, and one of the objects references the exit function. When the debugger tries to call __repr__ on that object to display that function to you, the program suddenly stops! That would be really unexpected, and the measures to counter that might complicate things further (for instance, even if you limit that behavior to the command line, what if you try to print some object that have exit as an attribute?)
With Anaconda 4.5+ and Python 3.6+ on Windows use
Ctrl+Z
or
exit()
In some cases, you might have to use
Ctrl+Break
If your computer doesn't have Break key then see here.
I recommend you exit the Python interpreter with Ctrl-D. This is the old ASCII code for end-of-file or end-of-transmission.
This message is the __str__ attribute of exit
look at these examples :
1
>>> print exit
Use exit() or Ctrl-D (i.e. EOF) to exit
2
>>> exit.__str__()
'Use exit() or Ctrl-D (i.e. EOF) to exit'
3
>>> getattr(exit, '__str__')()
'Use exit() or Ctrl-D (i.e. EOF) to exit'
Because the interpreter is not a shell where you provide commands, it's - well - an interpreter. The things that you give to it are Python code.
The syntax of Python is such that exit, by itself, cannot possibly be anything other than a name for an object. Simply referring to an object can't actually do anything (except what the read-eval-print loop normally does; i.e. display a string representation of the object).
You can fix that.
Link PYTHONSTARTUP to a python file with the following
# Make exit work as expected
type(exit).__repr__ = type(exit).__call__
How does this work?
The python command line is a read-evaluate-print-loop, that is when you type text it will read that text, evaluate it, and eventually print the result.
When you type exit() it evaluates to a callable object of type site.Quitter and calls its __call__ function which exits the system. When you type exit it evaluates to the same callable object, without calling it the object is printed which in turn calls __repr__ on the object.
We can take advantage of this by linking __repr__ to __call__ and thus get the expected behavior of exiting the system even when we type exit without parentheses.
To exit from Python terminal, simply just do:
exit()
Please pay attention it's a function which called as most user mix it with exit without calling, but new Pyhton terminal show a message...
or as a shortcut, press:
Ctrl + D
on your keyboard...
If you stuck in python command line and none of above solutions worked for you,
try exit(2)
"exit" is a valid variable name that can be used in your Python program. You wouldn't want to exit the interpreter when you're just trying to see the value of that variable.
This UX in python:
$ python
Python 3.10.5 (tags/v3.10.5:f377153, Jun 6 2022, 16:14:13) [MSC v.1929 64 bit (AMD64)] on win32
>>> ^D
File "<stdin>", line 1
♦
^
SyntaxError: invalid syntax
>>> exit
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'exit' is not defined
>>> quit
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'quit' is not defined
>>> exit()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'exit' is not defined
>>> quit()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'quit' is not defined

Categories