I'm writing an application that uses GDB to access information through java.
Using Runtime.getRuntime.exec, I'm able to attach GDB to any processes.
The problem is that I am unable to send inputs to GDB after it has been started.
**EDIT (19/8/2011):
At the line "out.println(gdbcommand)", gdb is started. How do I get the stdout of the newly spawned gdb, write inputs to it and then read the stdin. So far, I'm only able get the output up till "out.println(gdbcommand)". All attempts at trying to programmatically send inputs to gdb have not been working so far.**
Refer to trojanfoe's comments below my question. Below is an edited sample of my code:
try {
String gdbcommand = "/data/bin/gdb " + pidS + " " + pidS;
String line;
Process process = Runtime.getRuntime().exec("su");
if (process != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(process.getOutputStream())),true);
out.println(gdbcommand);
//Note this line does not get sent to gdb's interface after starting gdb.
//Is it possible to connect to the new stdout of gdb's interface?
out.println("info registers");
out.flush();
out.close();
while ((line = in.readLine()) != null) {
System.out.println(line);
}
process.destroy();
}
} catch (Exception e) {
e.printStackTrace();
}
Note that "info registers" is not sent to GDB's interface and after calling out.close(), gdb's interface quits. (As seen below)
08开发者_StackOverflow-18 14:40:36.595: INFO/System.out(4408): 0xafd0c51c in epoll_wait () from /system/lib/libc.so
08-18 14:40:36.595: INFO/System.out(4408): (gdb) Hangup detected on fd 0
08-18 14:40:36.595: INFO/System.out(4408): error detected on stdin
08-18 14:40:36.595: INFO/System.out(4408): The program is running. Quit anyway (and detach it)? (y or n) [answered Y; input not from terminal]
You need GDB/MI.
GDB/MI is a line based machine oriented text interface to GDB. It is specifically intended to support the development of systems which use the debugger as just one small component of a larger system.
Try and initiage GDB with --interpreter=mi
Ok if anybody is interested, the way I did this was to use a file to send the command to gdb instead.
`try {
String gdbcommand = "/data/bin/gdb " + pidsII + " " + pidsII + " < somefile.txt";
String line;
ArrayList<String> lines = new ArrayList<String>();
Process process = Runtime.getRuntime().exec("su");
if (process != null){
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(process.getOutputStream())),true);
out.println(gdbcommand);
out.flush();
out.flush();
out.close();
while ((line = in.readLine()) != null){
lines.add(line);
}
String[] lineArray = new String[lines.size()];
lineArray = lines.toArray(lineArray);
for (int i=0; i < lineArray.length; i++) {
System.out.println(lineArray[i].toString());
}
process.destroy();
}
} catch (Exception e) {
e.printStackTrace();
}`
Where somefile.txt contains the text info registers.
For some reason, not calling out.flush() three times would make the output not appear, hence the barrage of flushes.
Insread of
String[] command = {"/system/bin/sh", "-c", "su"};
maybe do a
String[] command = {"/system/bin/sh", "-c", "/data/bin/gdb " + pidS + " " + pidS};
or just
String[] command = {"/data/bin/gdb " + pidS + " " + pidS};
You just shouldn't close()
. Closing it sends EOF
.
gdb reads from stdin immediately upon starting, sees there's no input (and that it's not a terminal) and so immediately quits. To avoid this, you want to pass -batch to run it in batch mode, and then put the commands you wish to execute in a command file which you specify on the command line using the -x argument.
Your code would then be something like:
out.println("/data/bin/gdb -batch -x " + commandFilenameS + " " + pidS + " " + pidS);
精彩评论