dbTalk Databases Forums  

Minor problem with the resetdb

mailing.database.mysql-plusplus mailing.database.mysql-plusplus


Discuss Minor problem with the resetdb in the mailing.database.mysql-plusplus forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Earl Miles
 
Posts: n/a

Default Minor problem with the resetdb - 03-10-2005 , 07:40 PM






--------------020807080401020403020401
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

After the exceptions change there's a minor failure in the resetdb.cpp
that fails to check for an exception if it is unable to create the
sample database (which seems like a very common early error). Simply
adding a try/catch around that bit fixes it. Here's the diff, sent as an
attachment to prevent my mailer from word-wrapping it and destroying the
diff.


--------------020807080401020403020401
Content-Type: text/plain;
name="resetdb.exception.fix"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="resetdb.exception.fix"

--- ../../orig/mysql++-1.7.31/examples/resetdb.cpp 2005-03-05 00:07:20.000000000 -0800
+++ resetdb.cpp 2005-03-10 17:40:05.000000000 -0800
@@ -28,17 +28,24 @@
// Couldn't switch to the sample database, so assume that it
// doesn't exist and create it. If that doesn't work, exit
// with an error.
- if (con.create_db(kpcSampleDatabase)) {
- cerr << "Failed to create sample database." << endl;
- return 1;
+ try
+ {
+ if (con.create_db(kpcSampleDatabase)) {
+ cerr << "Failed to create sample database." << endl;
+ return 1;
+ }
+ else if (!con.select_db(kpcSampleDatabase)) {
+ cerr << "Failed to select sample database." << endl;
+ return 1;
+ }
+ else {
+ created = true;
+ }
}
- else if (!con.select_db(kpcSampleDatabase)) {
- cerr << "Failed to select sample database." << endl;
+ catch (exception& er) {
+ cerr << "Failed to create sample database: " << er.what() << endl;
return 1;
}
- else {
- created = true;
- }
}

mysqlpp::Query query = con.query(); // create a new query object


--------------020807080401020403020401
Content-Type: text/plain; charset=us-ascii

--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw
--------------020807080401020403020401--

Reply With Quote
  #2  
Old   
Warren Young
 
Posts: n/a

Default Re: Minor problem with the resetdb - 03-10-2005 , 10:45 PM






Earl Miles wrote:
Quote:
After the exceptions change there's a minor failure in the resetdb.cpp
that fails to check for an exception if it is unable to create the
sample database (which seems like a very common early error). Simply
adding a try/catch around that bit fixes it.
Sorry, Earl, this patch misses the entire point of that change. On some
platforms, nested exception handlers don't work. If an exception is
thrown from within a catch block, the program segfaults, even if it is
within a second catch block.

You're right, though, that a problem would occur if the second
select_db() call threw an exception. To fix this, I've added
disable_exceptions() and restore_exceptions() methods to the Connection
class. Note that these functions still work if throw_exceptions is
false initially, since the restore call just returns to the previous
value; it is not "enable_exceptions()".

Quote:
Here's the diff, sent as an
attachment to prevent my mailer from word-wrapping it and destroying the
diff.
Thanks for the effort, but it still got mangled. Line endings were DOS
(may be my mailer's fault, though I don't know why it would mess with an
attachment) and tabs were converted to spaces. I was still able to
apply it, but to prevent hassle in the future, I'd appreciate it if you
could see if either of these problems are something you can fix on your end.

Also, in one place you put a curly brace on the following line instead
of using K&R brace style, as the rest of the program uses. Please try
to maintain whatever style you see nearby when changing the code, no
matter how ugly it appears to you. I'm aware that the code style is
not consistent; I'm in the process of converting it piece by piece, as I
touch each file.

--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw



Reply With Quote
  #3  
Old   
Earl Miles
 
Posts: n/a

Default Re: Minor problem with the resetdb - 03-10-2005 , 10:50 PM



Warren Young wrote:
Quote:
Thanks for the effort, but it still got mangled. Line endings were DOS
(may be my mailer's fault, though I don't know why it would mess with an
attachment) and tabs were converted to spaces. I was still able to
apply it, but to prevent hassle in the future, I'd appreciate it if you
could see if either of these problems are something you can fix on your
end.
That's weird, I always save stuff using unix linefeeds. I think I have
tabs->spaces on my my editor by default as that was the coding style
I've always been made to use, since tabs are either 8 or 4 spaces
depending on your editor. I'll be sure to fix the setting for future
patches.

Quote:
Also, in one place you put a curly brace on the following line instead
of using K&R brace style, as the rest of the program uses. Please try
to maintain whatever style you see nearby when changing the code, no
matter how ugly it appears to you. I'm aware that the code style is
not consistent; I'm in the process of converting it piece by piece, as I
touch each file.

Darn, I thought I went back and fixed the {s to be in the right place. I
must've missed one. All I can say is shifting habits is hard. I'll try
to pay more attention next go 'round.

--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw



Reply With Quote
  #4  
Old   
Warren Young
 
Posts: n/a

Default Re: Minor problem with the resetdb - 03-10-2005 , 11:04 PM



Earl Miles wrote:

Quote:
Line endings were
DOS (may be my mailer's fault, though I don't know why it would mess
with an attachment)
Turns out this is the case. I re-sent a version of your patch with Unix
line endings to myself, and when I saved it again it was DOS. I work on
a Windows PC, and use my Linux boxes through ssh almost exclusively, so
my mailer is running on the Windows box.

--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw



Reply With Quote
  #5  
Old   
Warren Young
 
Posts: n/a

Default Re: Minor problem with the resetdb - 03-11-2005 , 01:01 AM



Warren Young wrote:

Quote:
You're right, though, that a problem would occur if the second
select_db() call threw an exception.
Turns out, this is extremely unlikely to occur. For it to happen,
create_db() -- which doesn't throw exceptions -- would have to succeed,
and then select_db() on the newly created database would have to fail.
I wouldn't be surprised if MySQL's security is fine-grained enough that
you could make a user that can create databases but not be able to
select them, but why would someone do such a thing?

I've withdrawn that change because it breaks the ABI, pointlessly.

--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw



Reply With Quote
  #6  
Old   
Earl Miles
 
Posts: n/a

Default Re: Minor problem with the resetdb - 03-11-2005 , 09:44 AM



Warren Young wrote:
Quote:
Warren Young wrote:

You're right, though, that a problem would occur if the second
select_db() call threw an exception.


Turns out, this is extremely unlikely to occur. For it to happen,
create_db() -- which doesn't throw exceptions -- would have to succeed,
and then select_db() on the newly created database would have to fail. I
wouldn't be surprised if MySQL's security is fine-grained enough that
you could make a user that can create databases but not be able to
select them, but why would someone do such a thing?

I've withdrawn that change because it breaks the ABI, pointlessly.

Hmm. In the instance I was toying with, the db already existed from a
previous run, and I was using the default user, who didn't have
permission with the database, so that's exactly what was happening in my
runs of resetdb. So not extremely unlikely, tho that is perhaps a pretty
edge case.

--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw



Reply With Quote
  #7  
Old   
Warren Young
 
Posts: n/a

Default Re: Minor problem with the resetdb - 03-11-2005 , 05:24 PM



Earl Miles wrote:

Quote:
Hmm. In the instance I was toying with, the db already existed from a
previous run, and I was using the default user, who didn't have
permission with the database, so that's exactly what was happening in my
runs of resetdb.
I think you need to debug that more closely. If the first select_db()
fails, it will try to create_db, which _doesn't throw exceptions_ when
it fails. It just returns true (!) so the program ends.

For your patch to have any value, you'd have to create the database
(again? how?) and then fail to select the database you just created.

--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw



Reply With Quote
  #8  
Old   
Earl Miles
 
Posts: n/a

Default Re: Minor problem with the resetdb - 03-11-2005 , 06:37 PM



Warren Young wrote:
Quote:
Earl Miles wrote:

Hmm. In the instance I was toying with, the db already existed from a
previous run, and I was using the default user, who didn't have
permission with the database, so that's exactly what was happening in
my runs of resetdb.


I think you need to debug that more closely. If the first select_db()
fails, it will try to create_db, which _doesn't throw exceptions_ when
it fails. It just returns true (!) so the program ends.

I think you are mistaken. create_db calls execute() which can, in fact,
throw exceptions. And does. At the bottom is my stepping through with
gdb, starting from a breakpoint at the catch() statement in resetdb.cpp

As I see it there are two possible solutions. The first being the one
you suggested--disable exceptions at will. I'm not sure how I feel about
that one. I have concerns over the safety of disabling exceptions and
ending up in a state where the program forgets to turn them back on. But
I'm not sure those concerns are well-founded, they are merely concerns.

The second would be to set a flag in the catch block, and once the catch
block is exited, check that flag and execute the code that is currently
in the catch block. Possibly a bit kludgy, but possibly safer than
simply disabling exceptions entirely, depending on whether or not my
concerns are valid.


(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program:
/home/emiles/downloads/mysql++-1.7.31/examples/.libs/resetdb

Breakpoint 1, main (argc=1, argv=0xbffff1b4) at resetdb.cpp:27
27 catch (mysqlpp::BadQuery &) {
(gdb) s
154 {
(gdb)
664 allocator() throw() {}
(gdb)
145 ResNSel execute(const std::string& str) {
(gdb)
std::basic_string<char, std::char_traits<char>, std::allocator<char> >
std:perator+<char, std::char_traits<char>, std::allocator<char> >(char
const*, std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const&) (
__lhs=0x807b7e1 "CREATE DATABASE ", __rhs=@0xbfffed70) at
char_traits.h:135
135 { return strlen(__s); }
(gdb)
614 {
(gdb)
135 { return strlen(__s); }
(gdb)
50 {
(gdb)
51 __asm__ __volatile__ ("lock; addl %0,%1"
(gdb)
208 : _Alloc(__a), _M_p(__dat) { }
(gdb)
229 { return _M_dataplus._M_p; }
(gdb)
388 size() const { return _M_rep()->_M_length; }
(gdb)
229 { return _M_dataplus._M_p; }
(gdb)
726 { return __lhs.base() - __rhs.base(); }
(gdb)
621 __str.append(__rhs);
(gdb)
622 return __str;
(gdb)
mysqlpp::Connection::execute(std::string const&, bool) (this=0xbfffed80,
str=@0x0, throw_excptns=true) at connection.h:90
90 if (locked) {
(gdb)
175 {
(gdb)
176 Success = false;
(gdb)
90 if (locked) {
(gdb)
93 locked = true;
(gdb)
89 {
(gdb)
229 { return _M_dataplus._M_p; }
(gdb)
119 { __c1 = __c2; }
(gdb)
781 {
(gdb)
119 { __c1 = __c2; }
(gdb)
781 {
(gdb)
188 if (Success) {
(gdb)
781 {
(gdb)
96 void unlock() { locked = false; }
(gdb)
188 if (Success) {
(gdb)
192 if (throw_excptns) {
(gdb)
106 const char *error() { return mysql_error(&mysql); }
(gdb)
664 allocator() throw() {}
(gdb)
106 const char *error() { return mysql_error(&mysql); }
(gdb)
12 BadQuery(const std::string &er = "") : error(er) {}
(gdb)
229 { return _M_dataplus._M_p; }
(gdb)
668 ~allocator() throw() {}
(gdb)
229 { return _M_dataplus._M_p; }
(gdb)
665 allocator(const allocator&) throw() {}
(gdb)
38 {
(gdb)
40 __asm__ __volatile__ ("lock; xaddl %0,%2"
(gdb)
38 {
(gdb)
193 throw BadQuery(error());
(gdb)
249 if (throw_exceptions) throw
BadQuery("ROW or RES is NULL");
(gdb)
193 throw BadQuery(error());
(gdb)

Program received signal SIGABRT, Aborted.
0x4018cda1 in kill () from /lib/libc.so.6
(gdb)
Single stepping until exit from function kill,
which has no line number information.

Program terminated with signal SIGABRT, Aborted.
The program no longer exists.
(gdb)



--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw



Reply With Quote
  #9  
Old   
Warren Young
 
Posts: n/a

Default Re: Minor problem with the resetdb - 03-11-2005 , 09:49 PM



Earl Miles wrote:

Quote:
I think you are mistaken.
Could be.

I see where I went wrong. The 'unprivileged' user I was using to test
had read ability on the test database, so he was able to select the
database the first time. You're probably using one that has no
privileges for the database whatsoever.

I dunno. I still don't see that this is very common.

Maybe we should talk about making a v1.8, where we break the ABI in
several ways at once? Take a look at the current Wishlist. There are
several items there that qualify.

Quote:
The second would be to set a flag in the catch block, and once the catch
block is exited, check that flag and execute the code that is currently
in the catch block. Possibly a bit kludgy, but possibly safer than
simply disabling exceptions entirely, depending on whether or not my
concerns are valid.
Do you know anything about scoped locks? Something similar could be
used here. Make an interface class that has functions for temporarily
disabling exceptions; derive Connection from it. Make another class
that takes a reference to an object with this interface, and calls the
disable function. When the disabler object goes out of scope, it calls
the re-enable function.

I've got an item for something similar for the Connection class's lock()
mechanism. It should use scoped locks, instead of the mechanism it
currently does.

--
MySQL++ Mailing List
For list archives: http://lists.mysql.com/plusplus
To unsubscribe: http://lists.mysql.com/plusplus?unsu...ie.nctu.edu.tw



Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.