Harding
October 23, 2025, 10:59am
1
According to The official Python docs
The prototype for save_database is:
def save_database(outfile: str=None, flags: int=-1, root: 'snapshot_t'=None,
attr: 'snapshot_t'=None) ->bool:
"""Save current database using a new file name.
:param outfile: output database file name; nullptr means the current path
:param flags: Database flags; -1 means the current flags
:param root: optional: snapshot tree root.
:param attr: optional: snapshot attributes
:returns: success"""
return _ida_loader.save_database(outfile, flags, root, attr)
However, one cannot call it:
TypeError Traceback (most recent call last)
Cell In[7], line 1
----> 1 ida_loader.save_database()
File <retracted>\ida_loader.py:715, in save_database(outfile, flags, root, attr)
706 def save_database(outfile: str=None, flags: int=-1, root: 'snapshot_t'=None,
707 attr: 'snapshot_t'=None) ->bool:
708 """Save current database using a new file name.
709
710 :param outfile: output database file name; nullptr means the current path
(...)
713 :param attr: optional: snapshot attributes
714 :returns: success"""
--> 715 return _ida_loader.save_database(outfile, flags, root, attr)
TypeError: Wrong number or type of arguments for overloaded function 'save_database'.
Possible C/C++ prototypes are:
save_database(char const *,uint32,snapshot_t const *,snapshot_t const *)
save_database(char const *,uint32,snapshot_t const *)
save_database(char const *,uint32)
save_database(char const *)
save_database()
The second argument is not int, it is uint32
Hi, thanks for the report! We’ll check why these calls aren’t working and follow up once we have more updates.
Hi @Harding ,
Indeed, the save_database() and save_database(char const *) are both unusable due to negative default value. One of these C++ vs Python inconsistencies that fell through the cracks.
Let me fix this upstream and make it available with the next release.
Until then, if you need the equivalent of idaapi.save_database(), you can use the following line:
idaapi.save_database(idaapi.get_path(idaapi.PATH_TYPE_IDB), 0)
Harding
October 27, 2025, 10:13am
4
Good you get it fixed. I have already made a “fix” for it by using ida_idaapi.as_uint32 as you can see here:
@param arg_snapshot_attribute: optional, snapshot attributes
@return success
'''
# TODO: Check how this plays with ida_domain
# TODO: How does this work with the flags? Like compressiong and so on? Should the user be able to set that in this function?
l_new_filename = arg_new_filename or None
l_my_extension = _os.path.splitext(input_file.idb_path)[1]
if l_new_filename and not l_new_filename.endswith(l_my_extension):
l_new_filename += l_my_extension
return _ida_loader.save_database(outfile=l_new_filename, flags=_ida_idaapi.as_uint32(arg_database_flags), root=arg_snapshot_root, attr=arg_snapshot_attribute)
@validate_call(config={"arbitrary_types_allowed": True, "strict": True, "validate_return": True})
def ida_exit(arg_exit_code: int = 0,
arg_save_database: bool = True,
arg_compress_database: bool = True,
arg_collect_garbage: bool = True) -> None:
''' Exit IDA and optionally save the IDB
A good use for this function is as the last call in a script run in batch mode.
See links() for more info about batch mode
1 Like
Nice, I see!
My fix changes the default to 0 instead of -1, but the functionality stays the same. Glad you found a way to work around.
1 Like