MudBytes
» MUDBytes Community » Language Discussions » C and C++ » C and MySQL causing string er...
Pages: << prev 1, 2 next >>
C and MySQL causing string errors.
Nash
Apprentice






Group: Members
Posts: 18
Joined: Jan 22, 2008

Go to the bottom of the page Go to the top of the page
#1 id:43021 Posted Mar 5, 2010, 12:58 pm

I've been fiddling with a MySQL engine, but if it reads in more than one query within about 2 seconds of each other, it causes lovely pointer errors. I am pretty sure it's a SQL error, despite the seg fault in sprintf, because when I comment out the second query, it loads data just fine.
Code (text):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 (gdb) bt 
 #0  0x00007f7915987030 in strlen () from /lib/libc.so.6 
 #1  0x00007f7915953cb1 in vfprintf () from /lib/libc.so.6 
 #2  0x00007f7915972dc9 in vsprintf () from /lib/libc.so.6 
 #3  0x000000000045c4af in printf_to_char (ch=0x13ef340, 
     fmt=0x536ee0 "(#%d)Guild Name: '%s%s{x'\n\rWho Title: '{g%s{x'\n\r") 
     at comm.c:2072 
 #4  0x000000000042fadf in do_guildstat (ch=0x13ef340, 
     argument=0x7fff1f3858da "skoth") at act_util.c:1130 
 #5  0x00000000004854c5 in interpret (ch=0x13ef340, 
     argument=0x7fff1f3858da "skoth") at interp.c:705 
 #6  0x0000000000441ff5 in substitute_alias (d=0x13ed690, 
     argument=0x13ee8c8 "guildstat skoth") at alias.c:58 
 #7  0x000000000045e9dc in game_loop_unix (control=4) at comm.c:334 
 #8  0x000000000045eec5 in main (argc=5, argv=0x7fff1f387048) at comm.c:136


Anyone familiar with MySQL C API, or what could be causing this problem?

Zeno
Wizard






Group: Moderators
Posts: 1,339
Joined: May 15, 2006

Go to the bottom of the page Go to the top of the page
#2 id:43023 Posted Mar 5, 2010, 1:05 pm

Can you show us what you comment out where it works?
.........................
-Zeno McDohl,
Owner of Bleached InuYasha Galaxy.
Zenorebirth: Free MUD host.
Learn how to build in Smaug at Smaug Building Institute.
Dragonball Z World is back: dbzw.uforce-hq.net 4000

Nash
Apprentice






Group: Members
Posts: 18
Joined: Jan 22, 2008

Go to the bottom of the page Go to the top of the page
#3 id:43026 Posted Mar 5, 2010, 1:56 pm

Code (text):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
void cql_load_db(){
	MYSQL_RES *res;
	MYSQL_ROW row;
	int i = 0,finished = false,status;
 
	for(int n = 0;n < MAX_GUILD;n++)
		init_blankguild(n);
 
	log_f("Loading dbs.");
	if(mysql_query(db,"SELECT * FROM houses; SELECT * FROM house_ranks;")){
//change the above line to if(mysql_query(db,"SELECT * FROM houses;")){
//and it all works fine
		log_f("cql_load_db() Error: %s",mysql_error(db));
		return;
	}
 
	do{
		log_f("1");
		res = mysql_store_result(db);
		if(res){
			cql_process_set(res);
			mysql_free_result(res);
		}
		else{
			if(!mysql_field_count(db))
				log_f("cql_load_db() : Number of rows affected: %lu\n",(unsigned long)mysql_affected_rows(db));
			else{
				log_f("cql_load_db() : Could not retrieve result set.");
				finished = true;
			}
		}
		status = mysql_next_result(db);
		if(status != 0){
			finished = true;
			if(status > 0)
				log_f("cql_load_db() : Could not execute statement.");
		}
	}while(!finished);
}

Last edited Mar 5, 2010, 1:57 pm by Nash
Tyche
Wizard






Group: Members
Posts: 1,702
Joined: May 23, 2006

Go to the bottom of the page Go to the top of the page
#4 id:43027 Posted Mar 5, 2010, 2:24 pm

Have you set the options for performing multiple queries?

Maybe try this:
log_f("Loading dbs.");
mysql_set_server_option(db, MYSQL_OPTION_MULTI_STATEMENTS_ON);
if(mysql_query(db,"SELECT * FROM houses; SELECT * FROM house_ranks;")){
.........................
Proud member of Team Hetero
http://jlsysinc.gotdns.com/ladybug_laugh2.jpghttp://jlsysinc.gotdns.com/teensymud_250x80.pnghttp://jlsysinc.gotdns.com/palin_calendar.jpg
For now we see through a glass, darkly; but then face to face: now I know in part; but then shall I know even as also I am known.

Nash
Apprentice






Group: Members
Posts: 18
Joined: Jan 22, 2008

Go to the bottom of the page Go to the top of the page
#5 id:43028 Posted Mar 5, 2010, 2:49 pm

That flag was not accepted. I had the following already set. When I changed it from clientmultistatements to mysqloptionmultistatementson, it would bounce back an error saying "; select * from houseranks;" was invalid syntax, which I guess means "multi statement is not on" When I set both flags, it gave the same error at the same location as when I had just my flag on.


Code (text):
1
2
3
4
5
6
7
8
9
10
11
void cql_init(){
	int opt_flags;
	opt_flags |= CLIENT_MULTI_STATEMENTS;
	db = mysql_init(NULL);
	if(!mysql_real_connect(db,NULL,"root","password","wake",0,NULL,opt_flags)){
		log_f("cql_init() Error: %s", mysql_error(db));
		return;
	}
}

Last edited Mar 5, 2010, 2:50 pm by Nash
Kline
Wizard






Group: Members
Posts: 724
Joined: Dec 14, 2007

Go to the bottom of the page Go to the top of the page
#6 id:43040 Posted Mar 5, 2010, 6:49 pm

Why exactly do you need to run two queries simultaneously? I have a game that makes fairly extensive use of MySQL (in C) but perhaps I'm too noob to realize why you'd ever need to run two at once like that.
.........................
AckFUSS -- Check it out.

Tyche
Wizard






Group: Members
Posts: 1,702
Joined: May 23, 2006

Go to the bottom of the page Go to the top of the page
#7 id:43041 Posted Mar 5, 2010, 7:11 pm

Okay. Yeah you can set the options in real_connect too.
What does cql_process_set() look like?


.........................
Proud member of Team Hetero
http://jlsysinc.gotdns.com/ladybug_laugh2.jpghttp://jlsysinc.gotdns.com/teensymud_250x80.pnghttp://jlsysinc.gotdns.com/palin_calendar.jpg
For now we see through a glass, darkly; but then face to face: now I know in part; but then shall I know even as also I am known.

Nash
Apprentice






Group: Members
Posts: 18
Joined: Jan 22, 2008

Go to the bottom of the page Go to the top of the page
#8 id:43042 Posted Mar 5, 2010, 11:07 pm

You'd want to run multiple queries all at once to load in data, as a replacement for flatfiles. I'm choosing to not have the lag overhead of calling all information on the fly from the DB, and instead just have SQL as a storage medium.

Here's the processor, the entry point is at the bottom because I'm lazy about prototypes when it's all contained in one file:

Code (text):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 
void cql_process_ranks(MYSQL_RES *res,MYSQL_FIELD *field){
	MYSQL_ROW row;
	int i,hid,rid;
 
	while((row = mysql_fetch_row(res))){
		hid = atoi(row[0]);
		rid = atoi(row[1]);
		guilds[hid].rank[rid].name		= str_dup(row[2]);
		guilds[hid].rank[rid].recruit	= atoi(row[3]);
		guilds[hid].rank[rid].expel		= atoi(row[4]);
		guilds[hid].rank[rid].promote	= atoi(row[5]);
		guilds[hid].rank[rid].demote	= atoi(row[6]);
	}
	if(mysql_errno(db) != 0)
		log_f("mysql_fetch_row() failed");
}
void cql_process_houses(MYSQL_RES *res,MYSQL_FIELD *field){
	MYSQL_ROW row;
	unsigned int i = 0;
 
	while((row = mysql_fetch_row(res))){
		log_f("'%s' '%s' '%s' '%d' '%d' '%d' '%d' '%d' '%d' '%d'",row[1],row[2],row[3],atoi(row[4]),atoi(row[5]),atoi(row[6]),atoi(row[7]),atoi(row[8]),atoi(row[9]),atoi(row[10]));
		guilds[i].name		= str_dup(row[1]);
		guilds[i].who_name	= str_dup(row[2]);
		guilds[i].keywords	= str_dup(row[3]);
		guilds[i].active	= atoi(row[4]);
		guilds[i].index		= atoi(row[5]);
		guilds[i].type		= atoi(row[6]);
		guilds[i].hidden	= atoi(row[7]);
		guilds[i].recall	= atoi(row[8]);
		guilds[i].respawn	= atoi(row[9]);
		guilds[i].area		= atoi(row[10]);
		i++;
	}
	if(mysql_errno(db) != 0)
		log_f("mysql_fetch_row() failed");
}
void cql_process_set(MYSQL_RES *res){
	MYSQL_FIELD *field = mysql_fetch_field(res);
	log_f(" >Loading table %s",field->table);
	if(!str_cmp(field->table,"houses"))
		cql_process_houses(res,field);
	else if(!str_cmp(field->table,"house_ranks"))
		cql_process_ranks(res,field);
}

Last edited Mar 5, 2010, 11:10 pm by Nash
Kline
Wizard






Group: Members
Posts: 724
Joined: Dec 14, 2007

Go to the bottom of the page Go to the top of the page
#9 id:43044 Posted Mar 6, 2010, 3:54 am

Nash said:
You'd want to run multiple queries all at once to load in data, as a replacement for flatfiles. I'm choosing to not have the lag overhead of calling all information on the fly from the DB, and instead just have SQL as a storage medium.


I do this too, but currently just have one or two VeryLong(tm) queries that run separately.
.........................
AckFUSS -- Check it out.

Tyche
Wizard






Group: Members
Posts: 1,702
Joined: May 23, 2006

Go to the bottom of the page Go to the top of the page
#10 id:43050 Posted Mar 6, 2010, 2:03 pm

Looks okay to me.

Seems to me you should go back and put a break point on line 2072 of comm.c..
#3  0x000000000045c4af in printf_to_char (ch=0x13ef340,
    fmt=0x536ee0 "(#%d)Guild Name: '%s%s{x'\n\rWho Title: '{g%s{x'\n\r")
    at comm.c:2072
#4  0x000000000042fadf in do_guildstat (ch=0x13ef340,
    argument=0x7fff1f3858da "skoth") at act_util.c:1130

Find out exactly which parameter in your printf_to_char() format string is fubared.

You could also code up a quick command to dump the contents of the two tables you've loaded in order to confirm they are okay.
.........................
Proud member of Team Hetero
http://jlsysinc.gotdns.com/ladybug_laugh2.jpghttp://jlsysinc.gotdns.com/teensymud_250x80.pnghttp://jlsysinc.gotdns.com/palin_calendar.jpg
For now we see through a glass, darkly; but then face to face: now I know in part; but then shall I know even as also I am known.

Last edited Mar 6, 2010, 2:06 pm by Tyche
Davion
Idle Hand






Group: Administrators
Posts: 1,537
Joined: May 14, 2006

Go to the bottom of the page Go to the top of the page
#11 id:43052 Posted Mar 6, 2010, 3:04 pm

You also may want to put a check in there to make sure the number of returned rows (can be gathered with mysql_num_rows() ) is not larger then the tables you're dumping them into. You could probably even size them on load.
.........................
http://mudbytes.net/mudbytessignature-davion2.png

Nash
Apprentice






Group: Members
Posts: 18
Joined: Jan 22, 2008

Go to the bottom of the page Go to the top of the page
#12 id:43053 Posted Mar 6, 2010, 3:57 pm

Code (text):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#4  0x000000000042fb3f in do_guildstat (ch=0x7f05a9941cc0,
    argument=0x7fffb412469a "skoth") at act_util.c:1130
1130            printf_to_char(ch,"(#%d)Guild Name: '%s%s{x'\n\rWho Title: '{g%s{x'\n\r",guilds[i].index,guilds[i].active ? "{G" : "{R",guilds[i].name,guilds[i].who_name);
(gdb) p i
$1 = 2
(gdb) p guilds[i].name
$2 = 0x7f05abf9a844 "The Kingdom of Skothgard"
(gdb) p guilds[i].active
$3 = false
(gdb) p guilds[i].index
$4 = 0
(gdb) p guilds[i].who_name
$5 = 0x7f0501010101 <Address 0x7f0501010101 out of bounds>
(gdb)

Kline
Wizard






Group: Members
Posts: 724
Joined: Dec 14, 2007

Go to the bottom of the page Go to the top of the page
#13 id:43054 Posted Mar 6, 2010, 4:16 pm

I'd say you found your issue with the out of bounds name.
.........................
AckFUSS -- Check it out.

Nash
Apprentice






Group: Members
Posts: 18
Joined: Jan 22, 2008

Go to the bottom of the page Go to the top of the page
#14 id:43055 Posted Mar 6, 2010, 4:34 pm

Not really. The why and how it's going out of bounds is the problem. When I have only one query, it doesn't go out of bounds. But when I have two, it does. I mentioned this in my original post that I already knew what the problem was (pointer error). I just can't figure out how it's being caused.

Last edited Mar 6, 2010, 4:41 pm by Nash
Tyche
Wizard






Group: Members
Posts: 1,702
Joined: May 23, 2006

Go to the bottom of the page Go to the top of the page
#15 id:43056 Posted Mar 6, 2010, 5:47 pm

Did your logf() in cql_process_houses print guild[x].who_name out at the time of the load?

.........................
Proud member of Team Hetero
http://jlsysinc.gotdns.com/ladybug_laugh2.jpghttp://jlsysinc.gotdns.com/teensymud_250x80.pnghttp://jlsysinc.gotdns.com/palin_calendar.jpg
For now we see through a glass, darkly; but then face to face: now I know in part; but then shall I know even as also I am known.

Last edited Mar 6, 2010, 5:47 pm by Tyche
Pages:<< prev 1, 2 next >>

Valid XHTML 1.1! Valid CSS!