In GDB is it possible to give an address relative (in lines) from the start of a function? - gdb

The subject line basically says it all.
If I give the location based on the file and a line number, that value can change if I edit the file. In fact it tends to change quite often and in an inconvenient way if I edit more than a single function during refactoring. However, it's less likely to change if it were (line-)relative to the beginning of a function.
In case it's not possible to give the line offset from the start of a function, then is it perhaps possible to use convenience variables to emulate it? I.e. if I would declare convenience variables that map to the start of a particular function (a list that I would keep updated)?
According to help break neither seems to be available, but I thought I'd better ask to be sure.
(gdb) help break
Set breakpoint at specified line or function.
break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM] [if CONDITION]
PROBE_MODIFIER shall be present if the command is to be placed in a
probe point. Accepted values are `-probe' (for a generic, automatically
guessed probe type) or `-probe-stap' (for a SystemTap probe).
LOCATION may be a line number, function name, or "*" and an address.
If a line number is specified, break at start of code for that line.
If a function is specified, break at start of code for that function.
If an address is specified, break at that exact address.
With no LOCATION, uses current execution address of the selected
stack frame. This is useful for breaking on return to a stack frame.
THREADNUM is the number from "info threads".
CONDITION is a boolean expression.
Multiple breakpoints at one place are permitted, and useful if their
conditions are different.
Do "help breakpoints" for info on other commands dealing with breakpoints.

It's a longstanding request to add this to gdb. However, it doesn't exist right now. It's maybe sort of possible with Python, but perhaps not completely, as Python doesn't currently have access to all the breakpoint re-set events (so the breakpoint might work once but not on re-run or library load or some other inferior change).
However, the quoted text shows a nicer way -- use an probe point. These are so-called "SystemTap probe points", but in reality they're more like a generic ELF + GCC feature -- they originated from the SystemTap project but don't depend on it. These let you mark a spot in the source and easily put a breakpoint on it, regardless of other edits to the source. They are already used on linux distros to mark special spots in the unwinder and longjump runtime routines to make debugging work nicely in the presence of these.

I understand that this is an old question, but I still could not find a better solution even now in 2017. Here's a Python solution. Maybe it's not the most robust/cleanest one, but it works very well in many practical scenarios:
class RelativeFunctionBreakpoint (gdb.Breakpoint):
def __init__(self, functionName, lineOffset):
super().__init__(RelativeFunctionBreakpoint.calculate(functionName, lineOffset))
def calculate(functionName, lineOffset):
"""
Calculates an absolute breakpoint location (file:linenumber)
based on functionName and lineOffset
"""
# get info about the file and line number where the function is defined
info = gdb.execute("info line "+functionName, to_string=True)
# extract file name and line number
m = re.match(r'Line[^\d]+(\d+)[^"]+"([^"]+)', info)
if not m:
raise Exception('Failed to find function %s.' % functionName)
line = int(m.group(1))+lineOffset #add the lineOffset
fileName = m.group(2)
return "%s:%d" % (fileName, line)
USAGE:
basic:
RelativeFunctionBreakpoint("yourFunctionName", lineOffset=5)
custom breakpoint:
class YourCustomBreakpoint (RelativeFunctionBreakpoint):
def __init__(self, funcName, lineOffset, customData):
super().__init__(funcName, lineOffset)
self.customData = customData
def stop(self):
# do something
# here you can access self.customData
return False #or True if you want the execution to stop
Advantages of the solution
relatively fast, because the breakpoint is set only once, before the execution starts
robust to changes in the source file if they don't affect the function
Disadvatages
Of course, it's not robust to the edits in the function itself
Not robust to the changes in the output syntax of the info line funcName gdb command (probably there is a better way to extract the file name and line number)
other? you point out

Related

Is it possible to register commands to a breakpoint from within an external file in GDB?

GDB allows registering a set of commands to a specific breakpoint via commands NUM syntax. I need to register the set of commands for a specific breakpoint via an external file, by using a syntax something like the following:
commands ./main.c:18
silent
print buffer[0]
cont
end
commands ./io.c:29
silent
printf "Hello world %i\n", myvar1
cont
end
The commands path/to/file:XX syntax is made up by me. Because the NUM in commands NUM syntax requires exactly the breakpoint's runtime ID number (assigned by GDB), I can not use a deterministic syntax for that purpose.
I'm currently registering breakpoints via a text file with such a content:
break ./main.c:18
break ./io.c:29
and then issuing source breakpoints.txt command inside GDB. It seems that there is no way to register commands at the same time while registering a breakpoint:
(gdb) help break
Set breakpoint at specified line or function.
break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM] [if CONDITION]
PROBE_MODIFIER shall be present if the command is to be placed in a
probe point. Accepted values are -probe' (for a generic, automatically guessed probe type), -probe-stap' (for a SystemTap probe) or
`-probe-dtrace' (for a DTrace probe).
LOCATION may be a line number, function name, or "*" and an address.
If a line number is specified, break at start of code for that line.
If a function is specified, break at start of code for that function.
If an address is specified, break at that exact address.
With no LOCATION, uses current execution address of the selected
stack frame. This is useful for breaking on return to a stack frame.
THREADNUM is the number from "info threads".
CONDITION is a boolean expression.
Multiple breakpoints at one place are permitted, and useful if their
conditions are different.
Question
Is there any easy way to set some predetermined commands for a predetermined breakpoint from within a file?
If not, is there any equivalent way to pass the (gdb) info breakpoints output to a file or a program while pipe is not available in GDB (version 5.3)? Currently I'm trying a workaround by using logging feature for that purpose:
set logging file /tmp/breakpoints
set logging on
info breakpoints
set logging off
Is there any easy way to set some predetermined commands for a predetermined breakpoint from within a file?
Yes: if you use commands without NUM, the commands will apply to the last breakpoint set. So you want something like:
break main.c:18
commands
silent
print buffer[0]
cont
end

setting a breakpoint in a specific line inside a function with 'gdb'

I am trying to set a breakpoint to the fifth line inside a member function of a class(a class that I created) with 'gdb'.
From here I understood just how to set a breakpoint at the begining of the the function,but I want to set it on a specific line inside the function, or a specific offset from the begining of this function.
In general is there a way in 'gdb' to set a breakpoint to a line by setting an offset from another breakpoint I already have ?
Thanks !
You can create a breakpoint at an offset from the current stopped position with gdb breakpoint +<offset>.
You can also create a breakpoint on a specific line number using either gdb break <linenumber> (for the current source file) or gdb break <filename>:<linenumber> (for a file other than the current file).
More details in the docs.
There isn't a way to set a breakpoint relative to the start of a function such that it will retain its relative position if the source file is modified. This would sometimes be useful; but it is just a feature that nobody has added to gdb.
It could maybe be emulated from Python, though it couldn't work exactly the way that ordinary breakpoints work, because Python doesn't have access to the breakpoint resetting mechanism inside gdb.
A one-shot solution can be done either as shown in the other answer or from Python.
When I have needed this sort of functionality -- a breakpoint mid-function that is reasonably robust against source changes -- I have used "SDT" static probe points. These let you name such spots in your source.
info fun <function name>
or fully qualified info functions <function name>
gets functions and their source files
list <function name>
Print lines centered around the beginning of function function.
Will list all function's source code, with some code below.
Choose line you want
break <filename:linenum>
Here's how you can automate it with python scripts for GDB:
class RelativeFunctionBreakpoint (gdb.Breakpoint):
def __init__(self, functionName, lineOffset):
super().__init__(RelativeFunctionBreakpoint.calculate(functionName, lineOffset))
def calculate(functionName, lineOffset):
"""
Calculates an absolute breakpoint location (file:linenumber)
based on functionName and lineOffset
"""
# get info about the file and line number where the function is defined
info = gdb.execute("info line "+functionName, to_string=True)
# extract file name and line number
m = re.match(r'Line[^\d]+(\d+)[^"]+"([^"]+)', info)
if not m:
raise Exception('Failed to find function %s.' % functionName)
line = int(m.group(1))+lineOffset #add the lineOffset
fileName = m.group(2)
return "%s:%d" % (fileName, line)
Basic usage:
RelativeFunctionBreakpoint("yourFunctionName", lineOffset=5)
You can also write a custom breakpoint. See more here:
https://stackoverflow.com/a/46737659/5787022
Using python to script GDB
Official documentation:
https://sourceware.org/gdb/onlinedocs/gdb/Python.html
Some exapmles: http://tromey.com/blog/?p=548

Is there a quick way to display the source code at a breakpoint in gdb?

I've set a breakpoint in gdb, and I'd like to see the exact line of source the breakpoint is on, just to confirm it's correct -- is there a quick way to do this?
The "info b" command gives me information about the breakpoints, but it doesn't display source:
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000006c3ba4 in MyClass::foo(bar*)
at /home/user1/src/MyClass.cpp:1021
I can type "list MyClass.cpp:1021" to see the lines around this breakpoint, but I'm wondering if there's a shorter way. Googling and reading the gdb manual didn't turn up anything.
I know that if I'm executing the program and have hit the breakpoint, I can just type "list", but I'm asking specifically about the case where I am not at the breakpoint (the program may not even be running).
You can use the list command to show sources. list takes a "linespec", which is gdb terminology for the kinds of arguments accepted by break. So, you can either pass it whatever argument you used to make the breakpoint in the first place (e.g., list function) or you can pass it the file and line shown by info b (e.g., list mysource.c:75).
I think the closest one can get to this is by turning the history on (set history save on) and then press CTRL-R to do a reverse search for the former list command.
More specifically, change your workflow when setting a breakpoint. After each command like b main GDB shows the source file like path/to/main.cpp, line 12. Immediately use this information in a quick list main.cpp:12. To show this location later press CTRL-R and type "main".
https://sourceware.org/gdb/onlinedocs/gdb/Command-History.html

gnuradio: how to change the noutput_items dynamically when writing OOT block?

When I make a OOT block in gnuradio
class mod(gr.sync_block):
"""
docstring for block mod
"""
def __init__(self):
gr.sync_block.__init__(self,
name="mod",
in_sig=[np.byte],
out_sig=[np.complex64])
def work(self, input_items, output_items):
in0 = input_items[0]
out = output_items[0]
result=do(....)
out[:]=result
return len(output_items[0])
I get:
ValueError: could not broadcast input array from shape (122879) into shape (4096)
How can I solve it?
GRC is as below:
selector :input index and output index are controlled by WX GUI Chooser block
FSK4 MOD: modulate fsk4 signal and write data to raw.bin
FSK4 DEMOD : read data from raw.bin and demodulate
file source -> /////// -> FSK4 MOD -> FSK4 DEMOD -> NULL SINK
selector
file source -> ////// -> GMKS MOD -> GMSK DEMOD ->NULL SINK
when the input index or output index is changed,the whole flow graph will be not responding.
There's two things:
You have a bug somewhere, and the solution is not to change something, but fix that bug. The full Python error message will tell you exactly in which line the error is.
noutput_items is a variable that GNU Radio sets at runtime to let you know how much output you might produce in this call to work. Hence, it's not something you can set, but it's something your work method must respect.
I think it's fair to assume that you're not very aware of how GNU Radio works:
GNU Radio is based on calling your block's work function when there is enough output space available and enough input items to process. The amount of output space that your block can use is passed to your work as a parameter, and will change between calls to work.
I very strongly recommend going through chapters 1-3 of the official Guided Tutorials if you haven't already. We always try to keep these tutorials up-to-date.
EDIT: Your command shows that you have not really understood what I meant, sorry. So: GNU Radio calls your work method over and over again while it's executing.
For example, it might call work with 4000 input items and 4000 output items space (you have a sync block, therefore number of input==number of output). Your work processes the first 1000 of that, and therefore return 1000. So there's 3000 items left.
Now, the upstream block does something, so there's 100 new items. Because the 3000 from before are still there, your block's work will get called with 3100 items.
Your work processes any number of items, and returns that number. GNU Radio makes sure that the "remaining" items stay available and will call your work again if there is enough in- our output.

Determing line number and file name of the perl file from within C++

I am working with Perl embedded in our application. We have installed quite a few C++ functions that are called from within Perl. One of them is a logging function. I would like to add the file name and line number of the Perl file that called this function to the log message.
I know on the Perl side I can use the "caller()" function to get this information, but this function is already used in hundreds of locations, so I would prefer to modify the C++ side, is this information passed to the C++ XSUB functions and if so how would I get at it?
Thanks.
This should work:
char *file;
I32 line;
file = OutCopFILE(PL_curcop);
line = CopLINE(PL_curcop);
Control ops (cops) are one of the two ops OP_NEXTSTATE and op_DBSTATE,
that (loosely speaking) are separate statements.
They hold information important for lexical state and error reporting.
At run time, PL_curcop is set to point to the most recently executed cop,
and thus can be used to determine our current state.
— cop.h
Can't you call perl builtins from XS? I confess I don't know.
If not, you could always do something like this:
sub logger { _real_logger(caller, #_) }
assuming logger is what your function is called (and you rename your C++ XS function to _real_logger. You could also do this, presumably, if you need to hide yourself in the call tree:
sub logger {
unshift #_, caller;
goto &_real_logger;
}
which is of course the normal form of goto used in AUTOLOAD.
These will add overhead, of course, but probably not a big deal for a logging function.