From 5776535a74189a9314468733009a85f0dfd97c2e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 1 Jun 2025 15:15:18 +0300 Subject: [PATCH 1/2] gh-66234: Add flag to disable the use of mmap in dbm.gnu This may harm performance, but improve crash tolerance. --- Doc/library/dbm.rst | 3 +++ Doc/whatsnew/3.15.rst | 8 ++++++ Lib/test/test_dbm_gnu.py | 27 +++++++++++++++++-- ...5-06-01-15-13-07.gh-issue-66234.Jw7OdC.rst | 3 +++ Modules/_gdbmmodule.c | 8 ++++++ 5 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-06-01-15-13-07.gh-issue-66234.Jw7OdC.rst diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst index 36221c026d6d4b..1901e16af41aa0 100644 --- a/Doc/library/dbm.rst +++ b/Doc/library/dbm.rst @@ -237,6 +237,9 @@ functionality like crash tolerance. * ``'s'``: Synchronized mode. Changes to the database will be written immediately to the file. * ``'u'``: Do not lock database. + * ``'m'``: Do not use :man:`mmap(2)`. + This may harm performance, but improve crash tolerance. + .. versionadded:: next Not all flags are valid for all versions of GDBM. See the :data:`open_flags` member for a list of supported flag characters. diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 6d1f653f086a15..510d99d20fd2f8 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -89,6 +89,14 @@ New modules Improved modules ================ +dbm +--- + +* Add the ``'m'`` flag for :func:`dbm.gnu.open` which allows to disable + the use of :man:`mmap(2)`. + This may harm performance, but improve crash tolerance. + (Contributed by Serhiy Storchaka in :gh:`66234`.) + difflib ------- diff --git a/Lib/test/test_dbm_gnu.py b/Lib/test/test_dbm_gnu.py index 66268c42a300b5..e0b988b7b95bbd 100644 --- a/Lib/test/test_dbm_gnu.py +++ b/Lib/test/test_dbm_gnu.py @@ -74,12 +74,12 @@ def test_flags(self): # Test the flag parameter open() by trying all supported flag modes. all = set(gdbm.open_flags) # Test standard flags (presumably "crwn"). - modes = all - set('fsu') + modes = all - set('fsum') for mode in sorted(modes): # put "c" mode first self.g = gdbm.open(filename, mode) self.g.close() - # Test additional flags (presumably "fsu"). + # Test additional flags (presumably "fsum"). flags = all - set('crwn') for mode in modes: for flag in flags: @@ -217,6 +217,29 @@ def test_localized_error(self): create_empty_file(os.path.join(d, 'test')) self.assertRaises(gdbm.error, gdbm.open, filename, 'r') + @unittest.skipUnless('m' in gdbm.open_flags, "requires 'm' in open_flags") + def test_nommap_no_crash(self): + self.g = g = gdbm.open(filename, 'nm') + os.truncate(filename, 0) + + g.get(b'a', b'c') + g.keys() + g.firstkey() + g.nextkey(b'a') + with self.assertRaises(KeyError): + g[b'a'] + with self.assertRaises(gdbm.error): + len(g) + + with self.assertRaises(gdbm.error): + g[b'a'] = b'c' + with self.assertRaises(gdbm.error): + del g[b'a'] + with self.assertRaises(gdbm.error): + g.setdefault(b'a', b'c') + with self.assertRaises(gdbm.error): + g.reorganize() + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Library/2025-06-01-15-13-07.gh-issue-66234.Jw7OdC.rst b/Misc/NEWS.d/next/Library/2025-06-01-15-13-07.gh-issue-66234.Jw7OdC.rst new file mode 100644 index 00000000000000..90062c4664bb70 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-06-01-15-13-07.gh-issue-66234.Jw7OdC.rst @@ -0,0 +1,3 @@ +Add the ``'m'`` flag for :func:`dbm.gnu.open` which allows to disable the +use of :man:`mmap(2)`. This may harm performance, but improve crash +tolerance. diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index 9c402e20e513b9..6a4939512b22fc 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -813,6 +813,11 @@ dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, case 'u': iflags |= GDBM_NOLOCK; break; +#endif +#ifdef GDBM_NOMMAP + case 'm': + iflags |= GDBM_NOMMAP; + break; #endif default: PyErr_Format(state->gdbm_error, @@ -846,6 +851,9 @@ static const char gdbmmodule_open_flags[] = "rwcn" #endif #ifdef GDBM_NOLOCK "u" +#endif +#ifdef GDBM_NOMMAP + "m" #endif ; From 2168ad165f0275bf0e9ff4629f36b9686491acbe Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 1 Jun 2025 15:55:54 +0300 Subject: [PATCH 2/2] Fix Sphinx markup. --- Doc/library/dbm.rst | 2 +- Doc/whatsnew/3.15.rst | 2 +- .../next/Library/2025-06-01-15-13-07.gh-issue-66234.Jw7OdC.rst | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst index 1901e16af41aa0..63a2bed10bd39f 100644 --- a/Doc/library/dbm.rst +++ b/Doc/library/dbm.rst @@ -237,7 +237,7 @@ functionality like crash tolerance. * ``'s'``: Synchronized mode. Changes to the database will be written immediately to the file. * ``'u'``: Do not lock database. - * ``'m'``: Do not use :man:`mmap(2)`. + * ``'m'``: Do not use :manpage:`mmap(2)`. This may harm performance, but improve crash tolerance. .. versionadded:: next diff --git a/Doc/whatsnew/3.15.rst b/Doc/whatsnew/3.15.rst index 510d99d20fd2f8..9b9572cdf2c0ea 100644 --- a/Doc/whatsnew/3.15.rst +++ b/Doc/whatsnew/3.15.rst @@ -93,7 +93,7 @@ dbm --- * Add the ``'m'`` flag for :func:`dbm.gnu.open` which allows to disable - the use of :man:`mmap(2)`. + the use of :manpage:`mmap(2)`. This may harm performance, but improve crash tolerance. (Contributed by Serhiy Storchaka in :gh:`66234`.) diff --git a/Misc/NEWS.d/next/Library/2025-06-01-15-13-07.gh-issue-66234.Jw7OdC.rst b/Misc/NEWS.d/next/Library/2025-06-01-15-13-07.gh-issue-66234.Jw7OdC.rst index 90062c4664bb70..1defb9a72e04e7 100644 --- a/Misc/NEWS.d/next/Library/2025-06-01-15-13-07.gh-issue-66234.Jw7OdC.rst +++ b/Misc/NEWS.d/next/Library/2025-06-01-15-13-07.gh-issue-66234.Jw7OdC.rst @@ -1,3 +1,3 @@ Add the ``'m'`` flag for :func:`dbm.gnu.open` which allows to disable the -use of :man:`mmap(2)`. This may harm performance, but improve crash +use of :manpage:`mmap(2)`. This may harm performance, but improve crash tolerance.