I can't figure out how to fully define a new parameter using the Python API in Gdb. A script that I source contains the following:
python
param = gdb.Parameter("test", gdb.COMMAND_NONE, gdb.PARAM_OPTIONAL_FILENAME)
param.set_doc = "This is the documentation" --> throws exception
end
I change and show its value in Gdb using:
(gdb) set test "hello world"
This command is not documented.
(gdb) show test
This command is not documented. "hello world"
The Gdb documentation mentions Parameter.set_doc, but when I try to assign to it I get the exception:
AttributeError: 'gdb.Parameter' object has no attribute 'set_doc'
How can I add this documentation, or how can I stop this "not documented" message from printing?
Although it may be possible to create a new parameter in gdb by instantiating gdb.Parameter directly and adding attributes later - maybe someone can answer that - the usual way is to define a new class, a subclass of gdb.Parameter, defining the necessary attributes such as set_doc in that class, and instantiating that class. Here's your example, reworked:
$ cat test.py
class TestParameter(gdb.Parameter):
"""Manage the test parameter.
Usage: set test filename
show test
"""
set_doc = "This is the single-line documentation for set test"
show_doc = "This is the single-line documentation for show test"
def __init__(self):
super(TestParameter, self).__init__("test", gdb.COMMAND_NONE,
gdb.PARAM_OPTIONAL_FILENAME)
self.value=""
def get_set_string(self):
return "You have set test to " + self.value
def get_show_string(self, _):
return "The value of test is " + self.value
TestParameter()
$ gdb -q
(gdb) source test.py
The following shows where and how the various doc strings are displayed:
(gdb) help set test
This is the single-line documentation for set test
Manage the test parameter.
Usage: set test filename
show test
(gdb) help show test
This is the single-line documentation for show test
Manage the test parameter.
Usage: set test filename
show test
(gdb) help set
...
List of set subcommands:
...
set test -- This is the single-line documentation for set test
...
Here's the output produced by set and show:
(gdb) set test .profile
You have set test to .profile
(gdb) show test
The value of test is .profile
Related
I don't understand why when I execute my code and I chose the first option he left without doing anything.
You will find below the code of my crystal script.
require "colorize"
class Application
def initialize
mainMenu
end
def mainMenu
puts "you are going to install the software?"
puts " 1: To install the soft you have to be root".colorize.fore(:red).bold
puts " 2: Modify module"
case gets
when "1"
puts "installation of the software.."
install_soft
when "2"
puts "you chose option2"
end
end
Application.new
end
This is the code of my install module with the methode install_soft.
He print correctly my puts " you are .." but it does nothing else :(
module InstallSoft
def install_soft
puts "you are in def install_soft "
output = IO::Memory.new
Process.run("bash", args: {"eole/lib/bash_scripts/installation.sh"}, output: output)
output.close
output.to_s
end
end
Well, what should it do? Your collecting the stdout of the process in a memory IO and convert it to string.
If you want to print the stdout of the process to the stdout of your app, you'll either have to forward it (use STDOUT instead of memory IO) or print the content of the memory IO to stdout (puts install_soft).
i found the solution i've to use
Process.run("lib/bash_scripts/installation.sh", shell: true, output: output)
output.close
output.to_s
but for the moment i cant get the output of my script :(
I found a solution to see the stack in live with output:true
Process.run("lib/bash_scripts/installation.sh", shell: true, output: true, error: true)
is there eval function? I've read "help" and I didnt find
I want to make eval("gdb command")
because I want to create my own function for grepping using this method
How to grep on gdb print.
I want to make eval($arg1)
There is an eval command, but it doesn't really do what you want. It provides a limited form of substitution of values into commands.
For a command along the lines of grep, I would suggest writing it in Python. This would be relatively easy to do. The idea would be to use gdb.execute to capture the output of a command into a string, and then use Python to search the string however you like. If done from Python you have complete control of how to parse the command-line, something that's not true if you use the gdb define command.
Oddly enough, I wrote a grep python gdb function earlier today for another question. These couple of files make a new command that checks if the call stack contains _malloc. This should be a pretty good start for other string searching and evaluation functions.
Here is a script for gdb
# gdb script: pygdb-logg.gdb
# easier interface for pygdb-logg.py stuff
# from within gdb: (gdb) source -v pygdb-logg.gdb
# from cdmline: gdb -x pygdb-logg.gdb -se test.exe
# first, "include" the python file:
source -v pygdb-logg.py
# define shorthand for inMalloc():
define inMalloc
python inMalloc()
end
Here is the python file:
#!/usr/bin/python
# gdb will 'recognize' this as python
# upon 'source pygdb-logg.py'
# however, from gdb functions still have
# to be called like:
# (gdb) python print logExecCapture("bt")
import sys
import gdb
import os
def logExecCapture(instr):
# /dev/shm - save file in RAM
ltxname="/dev/shm/c.log"
gdb.execute("set logging file "+ltxname) # lpfname
gdb.execute("set logging redirect on")
gdb.execute("set logging overwrite on")
gdb.execute("set logging on")
gdb.execute("bt")
gdb.execute("set logging off")
replyContents = open(ltxname, 'r').read() # read entire file
return replyContents
# in malloc?
def inMalloc():
isInMalloc = -1;
# as long as we don't find "Breakpoint" in report:
while isInMalloc == -1:
REP=logExecCapture("n")
#Look for calls that have '_malloc' in them
isInMalloc = REP.find("_malloc")
if(isInMalloc != -1):
# print ("Malloc:: ", isInMalloc, "\n", REP)
gdb.execute("set $inMalloc=1")
return True
else:
# print ("No Malloc:: ", isInMalloc, "\n", REP)
gdb.execute("set $inMalloc=0")
return False
I am new to GitPython and I am trying to get the content of a file within a commit. I am able to get each file from a specific commit, but I am getting an error each time I run the command. Now, I know that the file exist in GitPython, but each time I run my program, I am getting the following error:
returned non-zero exit status 1
I am using Python 2.7.6 and Ubuntu Linux 14.04.
I know that the file exist, since I also go directly into Git from the command line, check out the respective commit, search for the file, and find it. I also run the cat command on it, and the file contents are displayed. Many times when the error shows up, it says that the file in question does not exist. I am trying to go through each commit with GitPython, get every blob or file from each individual commit, and run an external Java program on the content of that file. The Java program is designed to return a string to Python. To capture the string returned from my Java code, I am also using subprocess.check_output. Any help will be greatly appreciated.
I tried passing in the command as a list:
cmd = ['java', '-classpath', '/home/rahkeemg/workspace/CSCI499_Java/bin/:/usr/local/lib/*:', 'java_gram.mainJava','absolute/path/to/file']
subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False)
And I have also tried passing the command as a string:
subprocess.check_output('java -classpath /home/rahkeemg/workspace/CSCI499_Java/bin/:/usr/local/lib/*: java_gram.mainJava {file}'.format(file=entry.abspath.strip()), shell=True)
Is it possible to access the contents of a file from GitPython?
For example, say there is a commit and it has one file foo.java
In that file is the following lines of code:
foo.java
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class foo{
public static void main(String[] args) throws Exception{}
}
I want to access everything in the file and run an external program on it.
Any help would be greatly appreciated. Below is a piece of the code I am using to do so
#! usr/bin/env python
__author__ = 'rahkeemg'
from git import *
import git, json, subprocess, re
git_dir = '/home/rahkeemg/Documents/GitRepositories/WhereHows'
# make an instance of the repository from specified path
repo = Repo(path=git_dir)
heads = repo.heads # obtain the different repositories
master = heads.master # get the master repository
print master
# get all of the commits on the master branch
commits = list(repo.iter_commits(master))
cmd = ['java', '-classpath', '/home/rahkeemg/workspace/CSCI499_Java/bin/:/usr/local/lib/*:', 'java_gram.mainJava']
# start at the very 1st commit, or start at commit 0
for i in range(len(commits) - 1, 0, -1):
commit = commits[i]
commit_num = len(commits) - 1 - i
print commit_num, ": ", commit.hexsha, '\n', commit.message, '\n'
for entry in commit.tree.traverse():
if re.search(r'\.java', entry.path):
current_file = str(entry.abspath.strip())
# add the current file or blob to the list for the command to run
cmd.append(current_file)
print entry.abspath
try:
# This is the scenario where I pass arguments into command as a string
print subprocess.check_output('java -classpath /home/rahkeemg/workspace/CSCI499_Java/bin/:/usr/local/lib/*: java_gram.mainJava {file}'.format(file=entry.abspath.strip()), shell=True)
# scenario where I pass arguments into command as a list
j_response = subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=False)
except subprocess.CalledProcessError as e:
print "Error on file: ", current_file
# Use pop on list to remove the last string, which is the selected file at the moment, to make place for the next file.
cmd.pop()
First of all, when you traverse the commit history like this, the file will not be checked out. All you get is the filename, maybe leading to the file or maybe not, but certainly it will not lead to the file from different revision than currently checked-out.
However, there is a solution to this. Remember that in principle, anything you could do with some git command, you can do with GitPython.
To get file contents from specific revision, you can do the following, which I've taken from that page:
git show <treeish>:<file>
therefore, in GitPython:
file_contents = repo.git.show('{}:{}'.format(commit.hexsha, entry.path))
However, that still wouldn't make the file appear on disk. If you need some real path for the file, you can use tempfile:
f = tempfile.NamedTemporaryFile(delete=False)
f.write(file_contents)
f.close()
# at this point file with name f.name contains contents of
# the file from path entry.path at revision commit.hexsha
# your program launch goes here, use f.name as filename to be read
os.unlink(f.name) # delete the temp file
I got the following errors when I run pxssh.pxssh() in python. Please let me know what I am missing here.
Exception AttributeError: "'pxssh' object has no attribute 'closed'" in <bound method pxssh.__del__ of <pexpect.pxssh.pxssh object at 0x10d98e910>> ignored
.........
File "/Users/any_user/system/somelibrary_lib.py", line 377, in login
ssh = pxssh.pxssh(maxread=read_buffer, ignore_sighup=False)
TypeError: __init__() got an unexpected keyword argument 'ignore_sighup'
.........
I faced the same problem. the solution was like this :
s = pxssh.pxssh(timeout=time_out, maxread=2000000)
s.SSH_OPTS += " -o StrictHostKeyChecking=no"
s.SSH_OPTS += " -o UserKnownHostsFile=/dev/null"
You should add this two options
I faced the same problem. Solution I found was to use SSH_OPTS property of pxssh object instead of options ctor (__init__) argument.
So my code looks like this:
s = pxssh.pxssh()
s.SSH_OPTS += " -o StrictHostKeyChecking=no"
s.force_password = True
s.login(ip, user, passwd)
It doesn't throw AttributeError exception on module initialization and TypeError too.
But it still doesn't work for me. If the remote server has MOTD or some shell initialization on startup, it would break the logic of pxssh. I made the following trick:
s.login(ip, user, passwd, original_prompt = "Last login:")
Shell writes on each successful login line like Last login: %date% from %ip%. I used it to verify successful logon. Now, using s you can execute remote commands.
Original (default) value for original_prompt is r"[#$]". May be you need somehow to combine them for correct pxssh work. May be you need to add > to original_prompt if you are connecting to SQL shell or Cisco devices.
I want to set a "rolling" breakpoint in gdb; there just print the current source line with some info; and then continue. I start with something like this:
break doSomething
commands
continue
end
This, on its own, prints out:
Breakpoint 1, doSomething () at myprog.c:55
55 void doSomething() {
I wanted to remove the "Breakpoint X ... at ..." message, which can be done with silent - and then printout just the source line; so I tried:
break doSomething
commands
silent
list
continue
end
This results with 10 lines of listing, like below
50 // some comments
...
55 void doSomething() {
...
59 // other comments
The problem is, saying list 1 will again give 10 lines, just starting from the first line; while doing list +0,+0 will indeed provide one line of source only - but the wrong line (in my case, it gives line 50).
So, then I realized that one can get and print the current program address by using the program counter $pc - and given that one can also list around a program address, I tried this:
break doSomething
commands
silent
#print $pc
list *$pc,+0
continue
end
This results with correct source line - but for some reason, again with an extra message, this time "ADDR is in X ..." :
0x8048fe0 is in doSomething (myprog.c:55).
55 void doSomething() {
Any ideas how to get only the source line to print?
As a sub-question - is it possible somehow to capture the output of the list command, and use it as an argument to printf in the gdb scripting dialect? (I'm pretty sure capturing gdb command output can be done through the python gdb scripting, though)...
Well, I think I got somewhere better with gdb's Python; now I can get the output to look like this (using gdb 7.3.50.20110806-cvs):
[ 56] 0x8048fe0 myprog.c:55 void doSomething() {
[ 56] 0x8049058 myprog.c:63 }
For the most part, I tried to use Symbol-Tables-In-Python to get to this (turns out there was an SO question about this, too: gdb find memory address of line number).
But, for some reason, when I use Symtab_and_line.line, which "Indicates the current line number for this object", it doesn't seem to change? In the above example, it is the first number in square brackets, and sits constantly at 56 (and is wrong in both cases). One would have hoped that the API would have had all that covered; and while the line number is there (albeit wrong?) - I couldn't find the string content of the respective source code line, as an object attribute, anywhere. On the other hand, when I use gdb.execute("list *$pc,+0") to query gdb directly about the current line as per OP, I get correct line numbers - but then, I have to additionally split and parse strings in Python :/
Still, better than nothing - here's the (Python embedded in gdb script) code; just throw it in your .gdbinit:
python
# example: these breakpoints do stop - but cannot change their
# stop method (which contains the "commands" for breakpoint in python)
#ax = gdb.Breakpoint("doSomething")
#print("hello", ax)
#print(dir(ax))
#print(ax.expression, ax.condition, ax.commands) # not writable!
#bx = gdb.Breakpoint("myprog.c:63")
# anything more than that - need to subclass:
class MyBreakpoint(gdb.Breakpoint):
def __init__(self, spec, command=""):
super(MyBreakpoint, self).__init__(spec, gdb.BP_BREAKPOINT,
internal = False)
self.command = command # not used
def stop(self):
# gdb.write - like print
# gdb.decode_line() - like gdb.find_pc_line(pc)
current_line = gdb.decode_line()
symtline = current_line[1][0]
#print(current_line, symtline.is_valid(), symtline.line , symtline.pc , symtline.symtab )
sysy = symtline.symtab
#print(sysy.filename, sysy.fullname(), sysy.is_valid() )
sysyo = sysy.objfile
#print(sysyo.filename, sysyo.is_valid(), sysyo.pretty_printers)
###print(gdb.solib_name()) # this breaks stuff??!
sourcefilename = sysy.filename
sourcefullpath = sysy.fullname()
sourcelinenum = symtline.line # somehow, it may be offset by 1, from what "list *$pc says"
listingline = gdb.execute("list *$pc,+0", to_string=True)
#print( "BREAK at %s:%d -- %s" % (sourcefilename, sourcelinenum, listingline) )
llsplit = listingline.split("\n")
listpreamble, gdbsourceline = llsplit[:2]
addr, noneed, noneed, funcname, fileloc = listpreamble.split(" ")[:5]
#linenum, sourceline = gdbsourceline.split("\t")[:2] # not using these - put gdb line verbatim
outline = "[% 4s] %s % 16s:%s" % (sourcelinenum, addr, sourcefilename[-16:], gdbsourceline)
print(outline)
return False # continue (do not stop inferior)
ax = MyBreakpoint("doSomething")
bx = MyBreakpoint("myprog.c:63")
end
run