FAQ
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.

Search Discussions

  • Warren Young at Mar 11, 2005 at 4:45 am

    Earl Miles wrote:
    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()".
    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.
  • Earl Miles at Mar 11, 2005 at 4:50 am

    Warren Young wrote:

    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.
    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.
  • Warren Young at Mar 11, 2005 at 5:04 am

    Earl Miles wrote:

    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.
  • Warren Young at Mar 11, 2005 at 7:01 am

    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.
  • Earl Miles at Mar 11, 2005 at 3:44 pm

    Warren Young wrote:
    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.
  • Warren Young at Mar 11, 2005 at 11:24 pm

    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.

    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.
  • Earl Miles at Mar 12, 2005 at 12:37 am

    Warren Young wrote:
    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::operator+<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)
  • Warren Young at Mar 12, 2005 at 3:49 am

    Earl Miles wrote:

    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.
    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.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupplusplus @
categoriesmysql
postedMar 11, '05 at 1:40a
activeMar 12, '05 at 3:49a
posts9
users2
websitemysql.com
irc#mysql

2 users in discussion

Warren Young: 5 posts Earl Miles: 4 posts

People

Translate

site design / logo © 2022 Grokbase