Index: doc/gdb.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v retrieving revision 1.955 diff -u -p -r1.955 gdb.texinfo --- doc/gdb.texinfo 6 May 2012 15:31:04 -0000 1.955 +++ doc/gdb.texinfo 7 May 2012 17:55:53 -0000 @@ -22392,6 +22392,53 @@ compute values, for example, it is the o convenience variable (@pxref{Convenience Vars}) as a @code{gdb.Value}. @end defun +@findex gdb.find_pc_line +@defun gdb.find_pc_line (pc [, actual]) +Return the @code{gdb.Symtab_and_line} object corresponding to the +@var{pc} value. If @var{actual} is @code{True}, it returns the +@code{gdb.Symtab_and_line} object with the actual line corresponding +to the pc value. Otherwise, it returns the @code{gdb.Symtab_and_line} +object with a line which the user feels the execution is currently at. +If @var{actual} is not specified, it defaults to @code{True}. +@xref{Symbol Tables In Python} + +The difference between @var{actual} being @code{True} or @code{False} +can be illustrated with an example. Let a call to a function @code{func} +be on line 20 in a C source file as + +@smallexample +18 ... +19 +20 func (); +21 +22 return 0; +23 +24 ... +@end smallexample + +After executing @value{GDBN} commands @code{step} followed by @code{up} +at line 20, the actual value of the @code{PC} register should correspond +to the next code line at line 22. However, since the function +@code{func} has not yet been executed, the user feels that the execution +is still at line 20 (the call site) in the caller. Hence, invoking + +@smallexample +gdb.find_pc_line (gdb.selected_frame().pc(), True) +@end smallexample + +@noindent +will return a @code{gdb.Symtab_and_line} object corresponding to the +actual line 22, while invoking + +@smallexample +gdb.find_pc_line (gdb.selected_frame().pc(), False) +@end smallexample + +@noindent +will return a @code{gdb.Symtab_and_line} object corresponding to the +call site line 20. +@end defun + @findex gdb.post_event @defun gdb.post_event (event) Put @var{event}, a callable object taking no arguments, into Index: python/python.c =================================================================== RCS file: /cvs/src/src/gdb/python/python.c,v retrieving revision 1.86 diff -u -p -r1.86 python.c --- python/python.c 30 Mar 2012 20:05:55 -0000 1.86 +++ python/python.c 7 May 2012 17:55:54 -0000 @@ -631,6 +631,28 @@ gdbpy_parse_and_eval (PyObject *self, Py return value_to_value_object (result); } +/* Implementation of gdb.find_pc_line function. + Returns the gdb.Symtab_and_line object corresponding to a PC value. */ + +static PyObject * +gdbpy_find_pc_line (PyObject *self, PyObject *args) +{ + struct symtab_and_line sal; + CORE_ADDR pc; + PyObject *actual = NULL; + int notcurrent = 0; + + if (!PyArg_ParseTuple (args, (GDB_PY_LLU_ARG "|O!"), &pc, &PyBool_Type, + &actual)) + return NULL; + + if (actual) + notcurrent = !PyObject_IsTrue (actual); + + sal = find_pc_line (pc, notcurrent); + return symtab_and_line_to_sal_object (sal); +} + /* Read a file as Python code. FILE is the file to run. FILENAME is name of the file FILE. This does not throw any errors. If an exception occurs python will print @@ -1458,6 +1480,14 @@ gdb.Symtab_and_line objects (or None)."} "parse_and_eval (String) -> Value.\n\ Parse String as an expression, evaluate it, and return the result as a Value." }, + { "find_pc_line", gdbpy_find_pc_line, METH_VARARGS, + "find_pc_line (pc[, actual]) -> Symtab_and_line.\n\ +Return the gdb.Symtab_and_line object corresponding to the pc value. If\n\ +actual is True, it returns the gdb.Symtab_and_line object with the actual\n\ +line corresponding to the pc value. Otherwise, it returns the\n\ +gdb.Symtab_and_line object with a line which the users feels the execution\n\ +is currently at. If actual is not specified, it defaults to True." + }, { "post_event", gdbpy_post_event, METH_VARARGS, "Post an event into gdb's event loop." }, Index: testsuite/gdb.python/python.c =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.python/python.c,v retrieving revision 1.4 diff -u -p -r1.4 python.c --- testsuite/gdb.python/python.c 4 Jan 2012 08:27:49 -0000 1.4 +++ testsuite/gdb.python/python.c 7 May 2012 17:55:59 -0000 @@ -23,6 +23,6 @@ int main (int argc, char *argv[]) { func1 (); - func2 (); + func2 (); /* Break at func2 call site. */ return 0; /* Break to end. */ } Index: testsuite/gdb.python/python.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.python/python.exp,v retrieving revision 1.32 diff -u -p -r1.32 python.exp --- testsuite/gdb.python/python.exp 30 Mar 2012 19:16:52 -0000 1.32 +++ testsuite/gdb.python/python.exp 7 May 2012 17:55:59 -0000 @@ -367,3 +367,23 @@ gdb_test_multiple "python gdb.prompt_hoo gdb_py_test_silent_cmd "python gdb.prompt_hook = None" \ "set the hook to default" 1 + +# Start with a fresh gdb. +clean_restart ${testfile} + +# The following tests require execution. + +if ![runto_main] then { + fail "Can't run to main" + return 0 +} + +runto [gdb_get_line_number "Break at func2 call site."] + +gdb_py_test_silent_cmd "step" "Step into func2" 1 +gdb_py_test_silent_cmd "up" "Step out of func2" 1 +gdb_py_test_silent_cmd "python line = gdb.selected_frame().find_sal().line" "Get line number of func2 call site" 1 + +# Test gdb.find_pc_line +gdb_test "python print gdb.find_pc_line(gdb.selected_frame().pc(), True).line > line" "True" "Get actual line" +gdb_test "python print gdb.find_pc_line(gdb.selected_frame().pc(), False).line == line" "True" "Get user line"