开发者

GDB scripting to MOCK

开发者 https://www.devze.com 2023-03-11 06:06 出处:网络
I am trying to mock a function (for unit testing parent function) using GDB. One way to do it would be to set a break point in function you intend to mock and use GDB return command.

I am trying to mock a function (for unit testing parent function) using GDB. One way to do it would be to set a break point in function you intend to mock and use GDB return command.

However I am unable to do the same when GDB call command is used.

(gdb) b secret_check
Breakpoint 1 at 0x80483ba: file ut_gdb.c, line 6.
(gdb) start
Temporary breakpoint 2 at 0x804843c: file ut_gdb.c, line 34.
Starting program: ut.bin
Temporary breakpoint 2, main () at ut_gdb.c:34
34          int res = 0;
(gdb) bt
#0  main () at ut_gdb.c:34
(gdb) call fact(3)
Breakpoint 1, secret_check (check_type=1) at ut_gdb.c:6
6               if(check_type == 0){
The program being debugged stopped while in a function called from GDB.
Evaluation of the expression 开发者_StackOverflow中文版containing the function
(fact) will be abandoned.
When the function is done executing, GDB will silently stop.
(gdb) bt
#0  secret_check (check_type=1) at ut_gdb.c:6
#1  0x080483ff in fact (n=3) at ut_gdb.c:19
#2  
#3  main () at ut_gdb.c:34

Is it a limitation in GDB ?


I would expect so. The limitation is probably that GDB cannot be stopped at (and able to continue from) two breakpoints at once. GDB has to maintain information about the current point where the program stopped in order to be able to continue. In order to support what you're trying to do, it would need to maintain a stack of "continue" states, and have some ability for you to specify which one you want to continue from.


It's possible to do this with GDB's Python interface:

import gdb

class MyBreak(gdb.Breakpoint):
  def __init__(self, spec):
    gdb.Breakpoint.__init__(self, spec)
    self.silent = True

  def stop(self):
    #do whatever you need

    return False

MyBreak("secret_check")

You need to be careful with what you do in the stop callback, not everything is legal. I don't mean it won't work, but it might crash and/or change in future versions for instance:

def stop(self):
  print gdb.selected_thread().is_running() # True
  gdb.execute("return 5") #working, but you're not really supposed to do it!
  ...

In the upcoming 7.4 version of GDB, the FinishBreakpoint should be able to help you a lot with your mocked functions (just an example, I didn't test it):

class MyFinishBreakpoint (gdb.FinishBreakpoint)
  def __init__(self, param):
    gdb.FinishBreakpoint()
    self.param = param

  def stop (self):
    #change self.param as you want
    return False

class MyBreak(gdb.Breakpoint):
  def stop(self):
    #read parameters according to calling conventions
    param = gdb.parse_and_eval("...")
    MyFinishBreakpoint(param)

    return False


Are you sure that this doesn't work? Just ignore the long message you get.

For my case fn1 calls fn2. I want to test fn1 and mock fn2:

b fn2
call fn1   
// gdb stops on the breakpoint
return somevalue
c

And everything seems OK. (I use cygwin gdb 7.8.)


Please take a look at: Debugging a programmatically called function with GDB

0

精彩评论

暂无评论...
验证码 换一张
取 消