dbTalk Databases Forums  

BadConverion::what()=Tried to convert "0.00P\uffffI" to a "d

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


Discuss BadConverion::what()=Tried to convert "0.00P\uffffI" to a "d in the mailing.database.mysql-plusplus forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
Drew Vogel
 
Posts: n/a

Default BadConverion::what()=Tried to convert "0.00P\uffffI" to a "d - 12-11-2005 , 12:01 PM






I am selecting 4 columns from a mysql table defined as

double NOT NULL default '0'

On line 4 below, a BadConversion exception is thrown, with the what()
message of:

Tried to convert "0.00P\uffffI" to a "d

The \uffff is output as a block font. The conversion to \uffff is done
by, I believe, GNOME's copy/paste.

1 double wpc1 = (double)row["wpc_slicing"];
2 double wpc2 = (double)row["wpc_piercing"];
3 double wpc3 = (double)row["wpc_chopping"];
4 double wpc4 = (double)row["wpc_bludgeoning"];

The first three lines are converted fine. The values print out in my log
as expected (I've omitted that code), which really puzzles me, because
the value in the columns of the third and the fourth row are the same
(0.0075). Any ideas what is causing the bad conversion and the
(apparently) malformed error message?

Drew Vogel


--
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
  #2  
Old   
Drew Vogel
 
Posts: n/a

Default Re: BadConverion::what()=Tried to convert "0.00P\uffffI" to a "d - 12-11-2005 , 12:28 PM






I should have been more clear in my previous post. When I say "The
values print out in my log as expected", I meant that the first three
values print out as expected and the fourth prints out as "0.00P\uffffI".


Drew Vogel wrote:

Quote:
I am selecting 4 columns from a mysql table defined as

double NOT NULL default '0'

On line 4 below, a BadConversion exception is thrown, with the what()
message of:

Tried to convert "0.00P\uffffI" to a "d

The \uffff is output as a block font. The conversion to \uffff is done
by, I believe, GNOME's copy/paste.

1 double wpc1 = (double)row["wpc_slicing"];
2 double wpc2 = (double)row["wpc_piercing"];
3 double wpc3 = (double)row["wpc_chopping"];
4 double wpc4 = (double)row["wpc_bludgeoning"];

The first three lines are converted fine. The values print out in my
log as expected (I've omitted that code), which really puzzles me,
because the value in the columns of the third and the fourth row are
the same (0.0075). Any ideas what is causing the bad conversion and
the (apparently) malformed error message?

Drew Vogel



--
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   
Warren Young
 
Posts: n/a

Default Re: BadConverion::what()=Tried to convert "0.00P\uffffI" to a "d - 12-12-2005 , 08:06 AM



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

Drew Vogel wrote:
Quote:
On line 4 below, a BadConversion exception is thrown, with the what()
message of:

Tried to convert "0.00P\uffffI" to a "d
I don't know why the message is truncated. Try the attached patch, to
see if the symptom changes. It just changes the way this message is
constructed.

As for why the error occurs, if the data truly is accurately represented
in that error, then there's no wonder it runs into a bad conversion.
That most definitely is not a valid double. What do you get when you
use the basic 'mysql' command-line client to dump the data from this
row? What if you try casting that fourth field to a std::string instead?

--------------090407050305030709080509
Content-Type: text/plain;
name="conv-error.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="conv-error.patch"

Index: coldata.h
================================================== =================
--- coldata.h (revision 1143)
+++ coldata.h (working copy)
@@ -46,6 +46,7 @@

#include <typeinfo>
#include <string>
+#include <sstream>

#include <stdlib.h>

@@ -324,7 +325,10 @@
}

if (*end != '\0' && end != 0) {
- throw BadConversion(typeid(Type).name(), Str::c_str(),
+ std:stringstream outs;
+ outs << "Tried to convert \"" << *this << "\" to a \"" <<
+ typeid(Type).name() << "\" object." << std::ends;
+ throw BadConversion(outs.str().c_str(), Str::c_str(),
end - str, len);
}

Index: exceptions.h
================================================== =================
--- exceptions.h (revision 1140)
+++ exceptions.h (working copy)
@@ -103,9 +103,8 @@
/// \param a ??
BadConversion(const char* tn, const char* d,
size_t r, size_t a) :
- Exception(std::string("Tried to convert \"") +
- std::string(d ? d : "") + "\" to a \"" +
- std::string(tn ? tn : "")),
+ Exception(std::string("Bad type conversion: ") +
+ std::string(d ? d : "<NULL>")),
type_name(tn),
data(d),
retrieved(r),


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


Reply With Quote
  #4  
Old   
Drew Vogel
 
Posts: n/a

Default Re: BadConverion::what()=Tried to convert "0.00P\uffffI" to a "d - 12-12-2005 , 08:19 AM



Warren Young wrote:

Quote:
Drew Vogel wrote:

On line 4 below, a BadConversion exception is thrown, with the what()
message of:

Tried to convert "0.00P\uffffI" to a "d


I don't know why the message is truncated. Try the attached patch, to
see if the symptom changes. It just changes the way this message is
constructed.

As for why the error occurs, if the data truly is accurately
represented in that error, then there's no wonder it runs into a bad
conversion. That most definitely is not a valid double. What do you
get when you use the basic 'mysql' command-line client to dump the
data from this row? What if you try casting that fourth field to a
std::string instead?

I will try the patch later today. Here is a copy/paste of my mysql
client output. When I cast the fourth field to a string, it doesn't
throw the BadConversion error, but the data is still corrupt. If I
select all of the columns in the table (named, not using *), the last
column (wpc_bludgeoning) is corrupted. When I select just the four wpc_*
columns, the data in the third column (wpc_chopping) corrupted. In both
scenerios, it corrupts the data in the last or third rows, respectively,
for both rows in the result set.


mysql> select * from character_classes;
+----+----------+------------+--------------+-------------+-------------+--------------+--------------+-----------------+
Quote:
id | name | max_health | max_strength | max_agility | wpc_slicing
wpc_piercing | wpc_chopping | wpc_bludgeoning |
+----+----------+------------+--------------+-------------+-------------+--------------+--------------+-----------------+
1 | knight | 100 | 100 | 75 | 0.01
0.0075 | 0.0075 | 0.0075 |
2 | assassin | 90 | 80 | 100 | 0.0075
0.01 | 0.005 | 0.005 |
+----+----------+------------+--------------+-------------+-------------+--------------+--------------+-----------------+
2 rows in set (0.09 sec)

mysql> select wpc_slicing, wpc_piercing, wpc_chopping, wpc_bludgeoning
from character_classes;
+-------------+--------------+--------------+-----------------+
Quote:
wpc_slicing | wpc_piercing | wpc_chopping | wpc_bludgeoning |
+-------------+--------------+--------------+-----------------+
0.01 | 0.0075 | 0.0075 | 0.0075 |
0.0075 | 0.01 | 0.005 | 0.005 |
+-------------+--------------+--------------+-----------------+
2 rows in set (0.00 sec)

mysql> show create table character_classes;
+-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Quote:
Table | Create
Table |
+-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Quote:
character_classes | CREATE TABLE `character_classes` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` char(16) NOT NULL default '',
`max_health` int(10) unsigned NOT NULL default '0',
`max_strength` int(10) unsigned NOT NULL default '0',
`max_agility` int(10) unsigned NOT NULL default '0',
`wpc_slicing` double NOT NULL default '0',
`wpc_piercing` double NOT NULL default '0',
`wpc_chopping` double NOT NULL default '0',
`wpc_bludgeoning` double NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.07 sec)


Drew Vogel

--
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: BadConverion::what()=Tried to convert "0.00P\uffffI" to a "d - 12-12-2005 , 09:48 AM



Drew Vogel wrote:
Quote:
If I
select all of the columns in the table (named, not using *), the last
column (wpc_bludgeoning) is corrupted. When I select just the four wpc_*
columns, the data in the third column (wpc_chopping) corrupted. In both
scenerios, it corrupts the data in the last or third rows, respectively,
for both rows in the result set.
Sounds like you have a memory bug somewhere. While it's possible that
it is in MySQL++, you'd think that someone else would have run into
something this blatant before.

If you're running on a Linux or OS X machine, try running your program
under valgrind. If on Windows, you may only have the choice of
commercial programs like Bounds Checker.

--
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   
Drew Vogel
 
Posts: n/a

Default Re: BadConverion::what()=Tried to convert "0.00P\uffffI" to a "d - 12-12-2005 , 12:38 PM



Warren Young wrote:
Quote:
Drew Vogel wrote:
If I
select all of the columns in the table (named, not using *), the last
column (wpc_bludgeoning) is corrupted. When I select just the four
wpc_* columns, the data in the third column (wpc_chopping) corrupted.
In both scenerios, it corrupts the data in the last or third rows,
respectively, for both rows in the result set.

Sounds like you have a memory bug somewhere. While it's possible that
it is in MySQL++, you'd think that someone else would have run into
something this blatant before.

If you're running on a Linux or OS X machine, try running your program
under valgrind. If on Windows, you may only have the choice of
commercial programs like Bounds Checker.

I'm not sure I actually solved this, but it went away. I went over the
execution path once more today (think fresh eyes might catch something
new). I realized that the Connection object was never closed or deleted.
I added a call to ->close() and a delete statement. Now the data
corruption is gone.

I am using the State Threads library, but the library never actually
creates a new thread (the exception was being thrown in the startup
code, before new threads are needed) so it is unlikely that this was
causing a problem. Any ideas how closing or not closing the Connection
object (well after the conversion is made) could have any effect on the
conversion? If anything, I would think that the data corruption would
happen if the conversion happened _after_ the connection was closed.

Drew Vogel

--
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: BadConverion::what()=Tried to convert "0.00P\uffffI" to a "d - 12-12-2005 , 03:52 PM



Drew Vogel wrote:
Quote:
I am using the State Threads library, but the library never actually
creates a new thread
Are you rebuilding MySQL++ with thread support, and linking your code to
the thread-safe version of the MySQL C API library? Are you observing
the thread safety requirements spelled out in the MySQL C API documentation?

Quote:
Any ideas how closing or not closing the Connection
object (well after the conversion is made) could have any effect on the
conversion?
Connection objects are designed to last the lifetime of the program, if
necessary. You do not have to close it in order to get good data. I
think all you have done is perturbed your bug into hiding from you; it's
still there, waiting to bite you again.

--
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   
Drew Vogel
 
Posts: n/a

Default Re: BadConverion::what()=Tried to convert "0.00P\uffffI" to a "d - 12-12-2005 , 04:03 PM



Warren Young wrote:
Quote:
Drew Vogel wrote:
I am using the State Threads library, but the library never actually
creates a new thread

Are you rebuilding MySQL++ with thread support, and linking your code
to the thread-safe version of the MySQL C API library? Are you
observing the thread safety requirements spelled out in the MySQL C
API documentation?
State Threads aren't preemptible. All mysql queries (at least at this
point) are done before the state threads library is even initalized.


Quote:
Any ideas how closing or not closing the Connection object (well
after the conversion is made) could have any effect on the conversion?

Connection objects are designed to last the lifetime of the program,
if necessary. You do not have to close it in order to get good data.
I think all you have done is perturbed your bug into hiding from you;
it's still there, waiting to bite you again.
Right, I'm closing the Connection object right before main() returns --
well after the conversion is made -- which is which it is so hard for me
to believe that this is what fixed it.



--
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   
Drew Vogel
 
Posts: n/a

Default Re: BadConverion::what()=Tried to convert "0.00P\uffffI" to a "d - 12-15-2005 , 08:07 PM



Drew Vogel wrote:

Quote:
Warren Young wrote:

Drew Vogel wrote:

If I
select all of the columns in the table (named, not using *), the
last column (wpc_bludgeoning) is corrupted. When I select just the
four wpc_* columns, the data in the third column (wpc_chopping)
corrupted. In both scenerios, it corrupts the data in the last or
third rows, respectively, for both rows in the result set.


Sounds like you have a memory bug somewhere. While it's possible
that it is in MySQL++, you'd think that someone else would have run
into something this blatant before.

If you're running on a Linux or OS X machine, try running your
program under valgrind. If on Windows, you may only have the choice
of commercial programs like Bounds Checker.


I'm not sure I actually solved this, but it went away. I went over the
execution path once more today (think fresh eyes might catch something
new). I realized that the Connection object was never closed or
deleted. I added a call to ->close() and a delete statement. Now the
data corruption is gone.

I am using the State Threads library, but the library never actually
creates a new thread (the exception was being thrown in the startup
code, before new threads are needed) so it is unlikely that this was
causing a problem. Any ideas how closing or not closing the Connection
object (well after the conversion is made) could have any effect on
the conversion? If anything, I would think that the data corruption
would happen if the conversion happened _after_ the connection was
closed.

After running into this same memory corruption again, I did a bit more
debugging. Through trial and error, I've determined that it only happens
when I declare a row object and then initialize it later:

mysqlpp::Row row;
while (row = res.fetch_row()) {
...
}

The memory corruption does not appear if I declare the row object inside
the loop condition:

while (mysqlpp::Row row = res.fetch_row()) {
...
}

The tutorial examples clearly imply that the first form is legitimate.
What am I missing here?

Drew Vogel



--
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
  #10  
Old   
Chris Frey
 
Posts: n/a

Default Re: BadConverion::what()=Tried to convert "0.00P\uffffI" to a "d - 12-19-2005 , 02:10 PM



On Thu, Dec 15, 2005 at 08:21:51PM -0600, Drew Vogel wrote:
Quote:
After running into this same memory corruption again, I did a bit more
debugging. Through trial and error, I've determined that it only happens
when I declare a row object and then initialize it later:

mysqlpp::Row row;
while (row = res.fetch_row()) {
...
}

The memory corruption does not appear if I declare the row object inside
the loop condition:

while (mysqlpp::Row row = res.fetch_row()) {
...
}
I don't see how that can make a difference. The examples use similar
logic to your first example, and they work.

The Row object is a rather simple container of data, and does its copying with
default copy constructor and default operator=().

Note that Row objects contain a pointer to the result object, so they must
not outlive the result.

- Chris


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