Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
5cd5f12a
Commit
5cd5f12a
authored
Sep 23, 2008
by
Jesus Cea
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bugfix for issue3885 and 'DB.verify()' crash.
Reviewed by Nick Coghlan.
parent
09979a13
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
123 additions
and
44 deletions
+123
-44
Lib/bsddb/test/test_basics.py
Lib/bsddb/test/test_basics.py
+36
-16
Modules/_bsddb.c
Modules/_bsddb.c
+86
-27
Modules/bsddb.h
Modules/bsddb.h
+1
-1
No files found.
Lib/bsddb/test/test_basics.py
View file @
5cd5f12a
...
@@ -573,6 +573,15 @@ class BasicTestCase(unittest.TestCase):
...
@@ -573,6 +573,15 @@ class BasicTestCase(unittest.TestCase):
#----------------------------------------
#----------------------------------------
def
test07_verify
(
self
):
# Verify bug solved in 4.7.3pre8
self
.
d
.
close
()
d
=
db
.
DB
(
self
.
env
)
d
.
verify
(
self
.
filename
)
#----------------------------------------
#----------------------------------------------------------------------
#----------------------------------------------------------------------
...
@@ -602,13 +611,13 @@ class BasicWithEnvTestCase(BasicTestCase):
...
@@ -602,13 +611,13 @@ class BasicWithEnvTestCase(BasicTestCase):
#----------------------------------------
#----------------------------------------
def
test0
7
_EnvRemoveAndRename
(
self
):
def
test0
8
_EnvRemoveAndRename
(
self
):
if
not
self
.
env
:
if
not
self
.
env
:
return
return
if
verbose
:
if
verbose
:
print
'
\
n
'
,
'-='
*
30
print
'
\
n
'
,
'-='
*
30
print
"Running %s.test0
7
_EnvRemoveAndRename..."
%
self
.
__class__
.
__name__
print
"Running %s.test0
8
_EnvRemoveAndRename..."
%
self
.
__class__
.
__name__
# can't rename or remove an open DB
# can't rename or remove an open DB
self
.
d
.
close
()
self
.
d
.
close
()
...
@@ -619,7 +628,7 @@ class BasicWithEnvTestCase(BasicTestCase):
...
@@ -619,7 +628,7 @@ class BasicWithEnvTestCase(BasicTestCase):
# dbremove and dbrename are in 4.1 and later
# dbremove and dbrename are in 4.1 and later
if
db
.
version
()
<
(
4
,
1
):
if
db
.
version
()
<
(
4
,
1
):
del
test0
7
_EnvRemoveAndRename
del
test0
8
_EnvRemoveAndRename
#----------------------------------------
#----------------------------------------
...
@@ -720,11 +729,11 @@ class BasicTransactionTestCase(BasicTestCase):
...
@@ -720,11 +729,11 @@ class BasicTransactionTestCase(BasicTestCase):
#----------------------------------------
#----------------------------------------
def
test0
7
_TxnTruncate
(
self
):
def
test0
8
_TxnTruncate
(
self
):
d
=
self
.
d
d
=
self
.
d
if
verbose
:
if
verbose
:
print
'
\
n
'
,
'-='
*
30
print
'
\
n
'
,
'-='
*
30
print
"Running %s.test0
7
_TxnTruncate..."
%
self
.
__class__
.
__name__
print
"Running %s.test0
8
_TxnTruncate..."
%
self
.
__class__
.
__name__
d
.
put
(
"abcde"
,
"ABCDE"
);
d
.
put
(
"abcde"
,
"ABCDE"
);
txn
=
self
.
env
.
txn_begin
()
txn
=
self
.
env
.
txn_begin
()
...
@@ -737,7 +746,7 @@ class BasicTransactionTestCase(BasicTestCase):
...
@@ -737,7 +746,7 @@ class BasicTransactionTestCase(BasicTestCase):
#----------------------------------------
#----------------------------------------
def
test0
8
_TxnLateUse
(
self
):
def
test0
9
_TxnLateUse
(
self
):
txn
=
self
.
env
.
txn_begin
()
txn
=
self
.
env
.
txn_begin
()
txn
.
abort
()
txn
.
abort
()
try
:
try
:
...
@@ -771,11 +780,11 @@ class BTreeRecnoTestCase(BasicTestCase):
...
@@ -771,11 +780,11 @@ class BTreeRecnoTestCase(BasicTestCase):
dbtype
=
db
.
DB_BTREE
dbtype
=
db
.
DB_BTREE
dbsetflags
=
db
.
DB_RECNUM
dbsetflags
=
db
.
DB_RECNUM
def
test0
7
_RecnoInBTree
(
self
):
def
test0
8
_RecnoInBTree
(
self
):
d
=
self
.
d
d
=
self
.
d
if
verbose
:
if
verbose
:
print
'
\
n
'
,
'-='
*
30
print
'
\
n
'
,
'-='
*
30
print
"Running %s.test0
7
_RecnoInBTree..."
%
self
.
__class__
.
__name__
print
"Running %s.test0
8
_RecnoInBTree..."
%
self
.
__class__
.
__name__
rec
=
d
.
get
(
200
)
rec
=
d
.
get
(
200
)
self
.
assertEqual
(
type
(
rec
),
type
(()))
self
.
assertEqual
(
type
(
rec
),
type
(()))
...
@@ -805,11 +814,11 @@ class BTreeRecnoWithThreadFlagTestCase(BTreeRecnoTestCase):
...
@@ -805,11 +814,11 @@ class BTreeRecnoWithThreadFlagTestCase(BTreeRecnoTestCase):
class
BasicDUPTestCase
(
BasicTestCase
):
class
BasicDUPTestCase
(
BasicTestCase
):
dbsetflags
=
db
.
DB_DUP
dbsetflags
=
db
.
DB_DUP
def
test0
8
_DuplicateKeys
(
self
):
def
test0
9
_DuplicateKeys
(
self
):
d
=
self
.
d
d
=
self
.
d
if
verbose
:
if
verbose
:
print
'
\
n
'
,
'-='
*
30
print
'
\
n
'
,
'-='
*
30
print
"Running %s.test0
8
_DuplicateKeys..."
%
\
print
"Running %s.test0
9
_DuplicateKeys..."
%
\
self
.
__class__
.
__name__
self
.
__class__
.
__name__
d
.
put
(
"dup0"
,
"before"
)
d
.
put
(
"dup0"
,
"before"
)
...
@@ -878,11 +887,11 @@ class BasicMultiDBTestCase(BasicTestCase):
...
@@ -878,11 +887,11 @@ class BasicMultiDBTestCase(BasicTestCase):
else
:
else
:
return
db
.
DB_BTREE
return
db
.
DB_BTREE
def
test
09
_MultiDB
(
self
):
def
test
10
_MultiDB
(
self
):
d1
=
self
.
d
d1
=
self
.
d
if
verbose
:
if
verbose
:
print
'
\
n
'
,
'-='
*
30
print
'
\
n
'
,
'-='
*
30
print
"Running %s.test
09
_MultiDB..."
%
self
.
__class__
.
__name__
print
"Running %s.test
10
_MultiDB..."
%
self
.
__class__
.
__name__
d2
=
db
.
DB
(
self
.
env
)
d2
=
db
.
DB
(
self
.
env
)
d2
.
open
(
self
.
filename
,
"second"
,
self
.
dbtype
,
d2
.
open
(
self
.
filename
,
"second"
,
self
.
dbtype
,
...
@@ -1014,9 +1023,20 @@ class DBPrivateObject(PrivateObject) :
...
@@ -1014,9 +1023,20 @@ class DBPrivateObject(PrivateObject) :
self
.
obj
=
db
.
DB
()
self
.
obj
=
db
.
DB
()
class
CrashAndBurn
(
unittest
.
TestCase
)
:
class
CrashAndBurn
(
unittest
.
TestCase
)
:
def
test01_OpenCrash
(
self
)
:
import
sys
# See http://bugs.python.org/issue3307
if
sys
.
version_info
[:
3
]
<
(
2
,
4
,
0
):
self
.
assertRaises
(
db
.
DBInvalidArgError
,
db
.
DB
,
None
,
65535
)
def
assertTrue
(
self
,
expr
,
msg
=
None
):
self
.
failUnless
(
expr
,
msg
=
msg
)
#def test01_OpenCrash(self) :
# # See http://bugs.python.org/issue3307
# self.assertRaises(db.DBInvalidArgError, db.DB, None, 65535)
def
test02_DBEnv_dealloc
(
self
):
# http://bugs.python.org/issue3885
import
gc
self
.
assertRaises
(
db
.
DBInvalidArgError
,
db
.
DBEnv
,
~
db
.
DB_RPCCLIENT
)
gc
.
collect
()
#----------------------------------------------------------------------
#----------------------------------------------------------------------
...
@@ -1044,7 +1064,7 @@ def test_suite():
...
@@ -1044,7 +1064,7 @@ def test_suite():
suite
.
addTest
(
unittest
.
makeSuite
(
HashMultiDBTestCase
))
suite
.
addTest
(
unittest
.
makeSuite
(
HashMultiDBTestCase
))
suite
.
addTest
(
unittest
.
makeSuite
(
DBEnvPrivateObject
))
suite
.
addTest
(
unittest
.
makeSuite
(
DBEnvPrivateObject
))
suite
.
addTest
(
unittest
.
makeSuite
(
DBPrivateObject
))
suite
.
addTest
(
unittest
.
makeSuite
(
DBPrivateObject
))
#
suite.addTest(unittest.makeSuite(CrashAndBurn))
suite
.
addTest
(
unittest
.
makeSuite
(
CrashAndBurn
))
return
suite
return
suite
...
...
Modules/_bsddb.c
View file @
5cd5f12a
...
@@ -989,7 +989,7 @@ newDBObject(DBEnvObject* arg, int flags)
...
@@ -989,7 +989,7 @@ newDBObject(DBEnvObject* arg, int flags)
/* Forward declaration */
/* Forward declaration */
static
PyObject
*
DB_close_internal
(
DBObject
*
self
,
int
flags
);
static
PyObject
*
DB_close_internal
(
DBObject
*
self
,
int
flags
,
int
do_not_close
);
static
void
static
void
DB_dealloc
(
DBObject
*
self
)
DB_dealloc
(
DBObject
*
self
)
...
@@ -997,8 +997,15 @@ DB_dealloc(DBObject* self)
...
@@ -997,8 +997,15 @@ DB_dealloc(DBObject* self)
PyObject
*
dummy
;
PyObject
*
dummy
;
if
(
self
->
db
!=
NULL
)
{
if
(
self
->
db
!=
NULL
)
{
dummy
=
DB_close_internal
(
self
,
0
);
dummy
=
DB_close_internal
(
self
,
0
,
0
);
Py_XDECREF
(
dummy
);
/*
** Raising exceptions while doing
** garbage collection is a fatal error.
*/
if
(
dummy
)
Py_DECREF
(
dummy
);
else
PyErr_Clear
();
}
}
if
(
self
->
in_weakreflist
!=
NULL
)
{
if
(
self
->
in_weakreflist
!=
NULL
)
{
PyObject_ClearWeakRefs
((
PyObject
*
)
self
);
PyObject_ClearWeakRefs
((
PyObject
*
)
self
);
...
@@ -1052,8 +1059,15 @@ DBCursor_dealloc(DBCursorObject* self)
...
@@ -1052,8 +1059,15 @@ DBCursor_dealloc(DBCursorObject* self)
PyObject
*
dummy
;
PyObject
*
dummy
;
if
(
self
->
dbc
!=
NULL
)
{
if
(
self
->
dbc
!=
NULL
)
{
dummy
=
DBC_close_internal
(
self
);
dummy
=
DBC_close_internal
(
self
);
Py_XDECREF
(
dummy
);
/*
** Raising exceptions while doing
** garbage collection is a fatal error.
*/
if
(
dummy
)
Py_DECREF
(
dummy
);
else
PyErr_Clear
();
}
}
if
(
self
->
in_weakreflist
!=
NULL
)
{
if
(
self
->
in_weakreflist
!=
NULL
)
{
PyObject_ClearWeakRefs
((
PyObject
*
)
self
);
PyObject_ClearWeakRefs
((
PyObject
*
)
self
);
...
@@ -1071,6 +1085,7 @@ newDBEnvObject(int flags)
...
@@ -1071,6 +1085,7 @@ newDBEnvObject(int flags)
if
(
self
==
NULL
)
if
(
self
==
NULL
)
return
NULL
;
return
NULL
;
self
->
db_env
=
NULL
;
self
->
closed
=
1
;
self
->
closed
=
1
;
self
->
flags
=
flags
;
self
->
flags
=
flags
;
self
->
moduleFlags
.
getReturnsNone
=
DEFAULT_GET_RETURNS_NONE
;
self
->
moduleFlags
.
getReturnsNone
=
DEFAULT_GET_RETURNS_NONE
;
...
@@ -1107,8 +1122,15 @@ DBEnv_dealloc(DBEnvObject* self)
...
@@ -1107,8 +1122,15 @@ DBEnv_dealloc(DBEnvObject* self)
PyObject
*
dummy
;
PyObject
*
dummy
;
if
(
self
->
db_env
)
{
if
(
self
->
db_env
)
{
dummy
=
DBEnv_close_internal
(
self
,
0
);
dummy
=
DBEnv_close_internal
(
self
,
0
);
Py_XDECREF
(
dummy
);
/*
** Raising exceptions while doing
** garbage collection is a fatal error.
*/
if
(
dummy
)
Py_DECREF
(
dummy
);
else
PyErr_Clear
();
}
}
Py_XDECREF
(
self
->
event_notifyCallback
);
Py_XDECREF
(
self
->
event_notifyCallback
);
...
@@ -1186,8 +1208,17 @@ DBTxn_dealloc(DBTxnObject* self)
...
@@ -1186,8 +1208,17 @@ DBTxn_dealloc(DBTxnObject* self)
if
(
self
->
txn
)
{
if
(
self
->
txn
)
{
int
flag_prepare
=
self
->
flag_prepare
;
int
flag_prepare
=
self
->
flag_prepare
;
dummy
=
DBTxn_abort_discard_internal
(
self
,
0
);
dummy
=
DBTxn_abort_discard_internal
(
self
,
0
);
Py_XDECREF
(
dummy
);
/*
** Raising exceptions while doing
** garbage collection is a fatal error.
*/
if
(
dummy
)
Py_DECREF
(
dummy
);
else
PyErr_Clear
();
if
(
!
flag_prepare
)
{
if
(
!
flag_prepare
)
{
PyErr_Warn
(
PyExc_RuntimeWarning
,
PyErr_Warn
(
PyExc_RuntimeWarning
,
"DBTxn aborted in destructor. No prior commit() or abort()."
);
"DBTxn aborted in destructor. No prior commit() or abort()."
);
...
@@ -1280,7 +1311,14 @@ DBSequence_dealloc(DBSequenceObject* self)
...
@@ -1280,7 +1311,14 @@ DBSequence_dealloc(DBSequenceObject* self)
if
(
self
->
sequence
!=
NULL
)
{
if
(
self
->
sequence
!=
NULL
)
{
dummy
=
DBSequence_close_internal
(
self
,
0
,
0
);
dummy
=
DBSequence_close_internal
(
self
,
0
,
0
);
Py_XDECREF
(
dummy
);
/*
** Raising exceptions while doing
** garbage collection is a fatal error.
*/
if
(
dummy
)
Py_DECREF
(
dummy
);
else
PyErr_Clear
();
}
}
if
(
self
->
in_weakreflist
!=
NULL
)
{
if
(
self
->
in_weakreflist
!=
NULL
)
{
...
@@ -1485,10 +1523,10 @@ DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
...
@@ -1485,10 +1523,10 @@ DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
static
PyObject
*
static
PyObject
*
DB_close_internal
(
DBObject
*
self
,
int
flags
)
DB_close_internal
(
DBObject
*
self
,
int
flags
,
int
do_not_close
)
{
{
PyObject
*
dummy
;
PyObject
*
dummy
;
int
err
;
int
err
=
0
;
if
(
self
->
db
!=
NULL
)
{
if
(
self
->
db
!=
NULL
)
{
/* Can be NULL if db is not in an environment */
/* Can be NULL if db is not in an environment */
...
@@ -1511,10 +1549,20 @@ DB_close_internal(DBObject* self, int flags)
...
@@ -1511,10 +1549,20 @@ DB_close_internal(DBObject* self, int flags)
}
}
#endif
#endif
MYDB_BEGIN_ALLOW_THREADS
;
/*
err
=
self
->
db
->
close
(
self
->
db
,
flags
);
** "do_not_close" is used to dispose all related objects in the
MYDB_END_ALLOW_THREADS
;
** tree, without actually releasing the "root" object.
self
->
db
=
NULL
;
** This is done, for example, because function calls like
** "DB.verify()" implicitly close the underlying handle. So
** the handle doesn't need to be closed, but related objects
** must be cleaned up.
*/
if
(
!
do_not_close
)
{
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db
->
close
(
self
->
db
,
flags
);
MYDB_END_ALLOW_THREADS
;
self
->
db
=
NULL
;
}
RETURN_IF_ERR
();
RETURN_IF_ERR
();
}
}
RETURN_NONE
();
RETURN_NONE
();
...
@@ -1526,7 +1574,7 @@ DB_close(DBObject* self, PyObject* args)
...
@@ -1526,7 +1574,7 @@ DB_close(DBObject* self, PyObject* args)
int
flags
=
0
;
int
flags
=
0
;
if
(
!
PyArg_ParseTuple
(
args
,
"|i:close"
,
&
flags
))
if
(
!
PyArg_ParseTuple
(
args
,
"|i:close"
,
&
flags
))
return
NULL
;
return
NULL
;
return
DB_close_internal
(
self
,
flags
);
return
DB_close_internal
(
self
,
flags
,
0
);
}
}
...
@@ -2146,7 +2194,7 @@ DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
...
@@ -2146,7 +2194,7 @@ DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
if
(
makeDBError
(
err
))
{
if
(
makeDBError
(
err
))
{
PyObject
*
dummy
;
PyObject
*
dummy
;
dummy
=
DB_close_internal
(
self
,
0
);
dummy
=
DB_close_internal
(
self
,
0
,
0
);
Py_XDECREF
(
dummy
);
Py_XDECREF
(
dummy
);
return
NULL
;
return
NULL
;
}
}
...
@@ -2840,21 +2888,24 @@ DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
...
@@ -2840,21 +2888,24 @@ DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
/* XXX(nnorwitz): it should probably be an exception if outFile
/* XXX(nnorwitz): it should probably be an exception if outFile
can't be opened. */
can't be opened. */
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db
->
verify
(
self
->
db
,
fileName
,
dbName
,
outFile
,
flags
);
MYDB_END_ALLOW_THREADS
;
if
(
outFile
)
fclose
(
outFile
);
{
/* DB.verify acts as a DB handle destructor (like close) */
{
/* DB.verify acts as a DB handle destructor (like close) */
PyObject
*
error
;
PyObject
*
error
;
error
=
DB_close_internal
(
self
,
0
);
error
=
DB_close_internal
(
self
,
0
,
1
);
if
(
error
)
{
if
(
error
)
{
return
error
;
return
error
;
}
}
}
}
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db
->
verify
(
self
->
db
,
fileName
,
dbName
,
outFile
,
flags
);
MYDB_END_ALLOW_THREADS
;
self
->
db
=
NULL
;
/* Implicit close; related objects already released */
if
(
outFile
)
fclose
(
outFile
);
RETURN_IF_ERR
();
RETURN_IF_ERR
();
RETURN_NONE
();
RETURN_NONE
();
}
}
...
@@ -3978,7 +4029,7 @@ DBEnv_close_internal(DBEnvObject* self, int flags)
...
@@ -3978,7 +4029,7 @@ DBEnv_close_internal(DBEnvObject* self, int flags)
Py_XDECREF
(
dummy
);
Py_XDECREF
(
dummy
);
}
}
while
(
self
->
children_dbs
)
{
while
(
self
->
children_dbs
)
{
dummy
=
DB_close_internal
(
self
->
children_dbs
,
0
);
dummy
=
DB_close_internal
(
self
->
children_dbs
,
0
,
0
);
Py_XDECREF
(
dummy
);
Py_XDECREF
(
dummy
);
}
}
}
}
...
@@ -4003,7 +4054,7 @@ DBEnv_close(DBEnvObject* self, PyObject* args)
...
@@ -4003,7 +4054,7 @@ DBEnv_close(DBEnvObject* self, PyObject* args)
if
(
!
PyArg_ParseTuple
(
args
,
"|i:close"
,
&
flags
))
if
(
!
PyArg_ParseTuple
(
args
,
"|i:close"
,
&
flags
))
return
NULL
;
return
NULL
;
return
DBEnv_close_internal
(
self
,
flags
);
return
DBEnv_close_internal
(
self
,
flags
);
}
}
...
@@ -5949,7 +6000,7 @@ DBTxn_abort_discard_internal(DBTxnObject* self, int discard)
...
@@ -5949,7 +6000,7 @@ DBTxn_abort_discard_internal(DBTxnObject* self, int discard)
}
}
#endif
#endif
while
(
self
->
children_dbs
)
{
while
(
self
->
children_dbs
)
{
dummy
=
DB_close_internal
(
self
->
children_dbs
,
0
);
dummy
=
DB_close_internal
(
self
->
children_dbs
,
0
,
0
);
Py_XDECREF
(
dummy
);
Py_XDECREF
(
dummy
);
}
}
...
@@ -6030,6 +6081,14 @@ DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close)
...
@@ -6030,6 +6081,14 @@ DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close)
self
->
txn
=
NULL
;
self
->
txn
=
NULL
;
}
}
/*
** "do_not_close" is used to dispose all related objects in the
** tree, without actually releasing the "root" object.
** This is done, for example, because function calls like
** "DBSequence.remove()" implicitly close the underlying handle. So
** the handle doesn't need to be closed, but related objects
** must be cleaned up.
*/
if
(
!
do_not_close
)
{
if
(
!
do_not_close
)
{
MYDB_BEGIN_ALLOW_THREADS
MYDB_BEGIN_ALLOW_THREADS
err
=
self
->
sequence
->
close
(
self
->
sequence
,
flags
);
err
=
self
->
sequence
->
close
(
self
->
sequence
,
flags
);
...
...
Modules/bsddb.h
View file @
5cd5f12a
...
@@ -105,7 +105,7 @@
...
@@ -105,7 +105,7 @@
#error "eek! DBVER can't handle minor versions > 9"
#error "eek! DBVER can't handle minor versions > 9"
#endif
#endif
#define PY_BSDDB_VERSION "4.7.3pre
5
"
#define PY_BSDDB_VERSION "4.7.3pre
9
"
/* Python object definitions */
/* Python object definitions */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment