Hello,
I'm writing an Ida Pro plugin, more precisely a multi-threaded IDAPython script. Basically the script runs a thread in the background and after calculating something (stumbling upon breakpoint), it will execute some action in the main GUI thread. Basically, I have to ensure that reading/writing to the IDB database is done in a safe manner and it must be done from the main thread, because the plugin will crash when done from the non-main thread.
Ida provides the idaapi.execute_sync function, which ensures the code is run in the main thread even if executed from a non-main thread. The function basically schedule a code that will be run in the main thread when it is safe to access the database. Below are the decorators that we can use for safe reading/writing to the IDB database: http://www.williballenthin.com/blog/201 ... decorator/.
From long hours of testing this, I've concluded that this happens at random intervals, but more importantly when the main thread is locked and execute_sync cannot execute the code in the main thread - you can try that by running the program and holding a left-mouse button pressed in Ida (which will occupy the main thread), and the program should crash right after being started: this is not always the case, probably because this is a timing issue and it's hard to obtain repeatable results with manual testing.
In any case, does anybody know how to proceed with the problem I've described.
I'm writing an Ida Pro plugin, more precisely a multi-threaded IDAPython script. Basically the script runs a thread in the background and after calculating something (stumbling upon breakpoint), it will execute some action in the main GUI thread. Basically, I have to ensure that reading/writing to the IDB database is done in a safe manner and it must be done from the main thread, because the plugin will crash when done from the non-main thread.
Ida provides the idaapi.execute_sync function, which ensures the code is run in the main thread even if executed from a non-main thread. The function basically schedule a code that will be run in the main thread when it is safe to access the database. Below are the decorators that we can use for safe reading/writing to the IDB database: http://www.williballenthin.com/blog/201 ... decorator/.
Code: Select all
In my plugin I'm using the following code:import functools
import idaapi
def idawrite(f):
"""
decorator for marking a function as modifying the IDB.
schedules a request to be made in the main IDA loop to avoid IDB corruption.
"""
@functools.wraps(f)
def wrapper(*args, **kwargs):
ff = functools.partial(f, *args, **kwargs)
return idaapi.execute_sync(ff, idaapi.MFF_WRITE)
return wrapper
def idaread(f):
"""
decorator for marking a function as reading from the IDB.
schedules a request to be made in the main IDA loop to avoid
inconsistent results.
MFF_READ constant via: http://www.openrce.org/forums/posts/1827
"""
@functools.wraps(f)
def wrapper(*args, **kwargs):
ff = functools.partial(f, *args, **kwargs)
return idaapi.execute_sync(ff, idaapi.MFF_READ)
return wrapper
Code: Select all
Ida pro crashes with the following warning dialog, where's it's evident that the crash occurs right after printing "WRAPPER2", but before the "WRAPPER3" - in the "val = idaapi.execute_sync(ff, idaapi.MFF_WRITE)" line.def idawrite(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
logger.debug("WRAPPER1")
ff = functools.partial(f, *args, **kwargs)
logger.debug("WRAPPER2")
val = idaapi.execute_sync(ff, idaapi.MFF_WRITE)
logger.debug("WRAPPER3")
return val
return wrapper
class MyDebugger(idaapi.DBG_Hooks):
"""
Class for debugging program by using IDA debug hooking functionality.
"""
def __init__(self):
pass
@idawrite
def process_continue(self):
"""
Continue the debugging session.
"""
#idaapi.msg("Continuing process execution.\n")
logger.debug("G1")
idaapi.request_continue_process()
logger.debug("G2")
idaapi.run_requests()
logger.debug("G3")
...
From long hours of testing this, I've concluded that this happens at random intervals, but more importantly when the main thread is locked and execute_sync cannot execute the code in the main thread - you can try that by running the program and holding a left-mouse button pressed in Ida (which will occupy the main thread), and the program should crash right after being started: this is not always the case, probably because this is a timing issue and it's hard to obtain repeatable results with manual testing.
In any case, does anybody know how to proceed with the problem I've described.