Nash
Apprentice


Group: Members
Posts: 18
Joined: Jan 22, 2008
|
#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?
|
|
|
|
|
Nash
Apprentice


Group: Members
Posts: 18
Joined: Jan 22, 2008
|
#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
|
|
|
|
Nash
Apprentice


Group: Members
Posts: 18
Joined: Jan 22, 2008
|
#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
|
|
|
|
|
|
Nash
Apprentice


Group: Members
Posts: 18
Joined: Jan 22, 2008
|
#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
|
#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.
|
|
|
|
|
|
|
Nash
Apprentice


Group: Members
Posts: 18
Joined: Jan 22, 2008
|
#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) |
|
|
|
|
|
Nash
Apprentice


Group: Members
Posts: 18
Joined: Jan 22, 2008
|
#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
|
|
|
|