GDB script for MOCK

I am trying to make fun of a function (for unit testing a parent function) using GDB. One way to do this is to set a breakpoint in the function you are about to mock and use the GDB return command.

However, I cannot do the same when using the GDB call command.

  (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 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 this a limitation in GDB?

+3
source share
3 answers

I would expect so. Probably the limitation is that GDB cannot be stopped (and can continue) from two breakpoints at once. GDB must maintain information about the current point where the program is stopped in order to be able to continue. In order to support what you are trying to do, he will need to maintain a β€œcontinue” state stack and be able to specify which one you want to continue with.

0
source

This can be done using the GDB 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 what you do in the stop callback, but not everything is legal. I do not mean that this will not work, but may lead to a crash and / or change in future versions, for example:

 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 version 7.4 of GDB, FinishBreakpoint should be able to help you with your mocking features (just an example, I have not tested 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 
0
source

Are you sure this will not work? Just ignore the long message you receive.

In my case, fn1 calls fn2. I want to check fn1 and mock fn2:

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

And everything seems OK. (I am using cygwin gdb 7.8.)


Please take a look at: Debugging a software-called function using GDB

0
source

Source: https://habr.com/ru/post/1393271/


All Articles