MySQL-API: Strange Errors

This is a discussion on MySQL-API: Strange Errors within the C Programming forums, part of the General Programming Boards category; Hi guys! Sorry for my bad english. It's not my native language. I'm working for about 2 weeks on a ...

  1. #1
    Registered User Kolazomai's Avatar
    Join Date
    Aug 2006
    Posts
    12

    Unhappy MySQL-API: Strange Errors. Source opened !

    Hi guys!

    Sorry for my bad english. It's not my native language.

    I'm working for about 2 weeks on a Software-Project using the C MySQL-API.

    It's a Server, that should be able to deal with several clients. I'm using select.

    Let me first describe, how everything works:

    I'm connecting to the MySQL-DB and create, if not already exist, my database and the tables I need. Then I bind a socket to a specified port, start a loop with select in it. Some Client connects, and so on. Nothing of interest now. I receive data from the client and call a split_-function, that splits this data for me:

    Code:
    char **split_(const char split_char,const char *string_) {
    
    int tmp = 0;
    int nr_of_split_chars = 0;
    
    for (tmp = 0;tmp <= strlen(string_);tmp++) {
    	if (string_[tmp] == split_char) {
    		nr_of_split_chars++;
    		}
    	}
    
    if (nr_of_split_chars == 0) {
    	return NULL;
    	}
    
    
    char **ret;
    ret = (char **)malloc(nr_of_split_chars * sizeof(*ret));
    
    for (tmp = 0;tmp <= nr_of_split_chars;tmp++) {
    	ret[tmp] = (char *)malloc(_MAX_SIZE_SPLIT);
    	if (ret[tmp] == NULL) {
    		printf("[-] Couldn't allocate %i Bytes ... Poor Boy\n",_MAX_SIZE_SPLIT);
    		}
    	}
    
    
    int current = 0;
    int last = 0;
    
    for (tmp = 0;tmp < strlen(string_);tmp++) {
    	if (string_[tmp] == split_char) {
    		ret[current][last] = '\0';
    		printf("[!] Split: \"%s\"\n",ret[current]);
    		current++;
    		last = 0;
    		continue;
    		}
    	if (string_[tmp] != '\r') {
    		ret[current][last] = string_[tmp];
    		last++;
    		}
    	if (tmp == (strlen(string_) - 1)) {
    		ret[current][last+1] = '\0';
    		printf("[!] End of Split: \"%s\"\n",ret[current]);
    		break;
    		}
    	}
    
    memmove(&split_nr,&current,sizeof(int));
    return ret;
    }

    The command the client is sending me is "ADD USER username password". If i split this data with the split_(' ',what_client_sent_me); everything seems to be fine.

    I'm calling now a function "mysql_register_user_(const char *username,const char*password)", that looks like that:
    Code:
    int mysql_register_user_(const char *username,const char *password) {
    
    #ifdef DEBUG
    printf("registering user\n\"%s\":\"%s\"\n",username,password);
    #endif
    
    unsigned long nr_of_res;
    char *tmp_qry;
    tmp_qry = (char *)malloc(_STD_SQL_CHAR);
    if (tmp_qry == NULL) {
    	fprintf(stderr,"[-] FATAL: Couldn't allocate %i bytes ... poor boy\n",_STD_SQL_CHAR);
    	exit(-1);
    	}
    
    snprintf(tmp_qry,_STD_SQL_CHAR - 1,
    		"SELECT * FROM %s WHERE username='%s'",
    		_USER_TABLE_NAME,username);
    
    
    if (mysql_real_query(sql_conn.my,tmp_qry,strlen(tmp_qry)) != 0) {
    	#ifdef DEBUG
    	printf("[-] mysql_register_user_() -> Querry was:\n\"%s\"\n",tmp_qry);
    	fflush(stdout);
    	#endif
    	if (check_error_() == -1) {
    		fprintf(stderr,"[-] FATAL: Couldn't read from %s\n",_USER_TABLE_NAME);
    		exit(-1);
    		}
    	free(tmp_qry);
    	return (-1);
    	}
    
    
    MYSQL_RES *results;
    results = mysql_store_result(sql_conn.my);
    if (results == NULL) {
    	if (check_error_() == -1) {
    		fprintf(stderr,"[-] FATAL: Couldn't execute a SELECT-Command\n");
    		free(tmp_qry);
    		return (-1);
    		}
    	}
    
    
    nr_of_res = (unsigned long)mysql_num_rows(results);
    if (nr_of_res != 0) {
    	/* There's another user, who already got this name */
    	mysql_free_result(results);
    	free(tmp_qry);
    	return (-2);
    	}
    
    snprintf(tmp_qry,_STD_SQL_CHAR - 1,
    		"INSERT INTO %s (username,password,uploads,downloads,rating,nr_of_ratings,"
    		"names_of_guys_ive_rated)"
    		" VALUES ('%s','%s',0,0,0.00,0,'%s')",
    		_USER_TABLE_NAME,username,password,username);
    
    
    if (mysql_real_query(sql_conn.my,tmp_qry,strlen(tmp_qry)) != 0) {
    	check_error_();
    	fprintf(stderr,"[-] FATAL: Couldn't create a new user !\n");
    	mysql_free_result(results);
    	free(tmp_qry);
    	return (-1);
    	}
    	
    
    
    #ifdef DEBUG
    printf("[+] Successfully added a new client to the DB\n");
    #endif
    
    mysql_free_result(results);
    free(tmp_qry);
    return 0;
    }
    Ok, now my strange Problem:

    If i call this function "native" ( e.g. mysql_register_user_("test","hello_world"); ) everything works fine. But in this context it does NOT work.

    Code:
    int _start_client(SOCKET cliefd) {
    
    #ifdef WIN32
    unsigned long ul = 1;
    ioctlsocket(cliefd, FIONBIO, &ul);
    #else
    fcntl(cliefd, F_SETFL, O_NONBLOCK);
    #endif
    
    
    char *buf;
    char *full;
    int tmp = 0;
    
    
    full = (char *)malloc(sizeof(char) * sizeof(struct ks_upload) + 25 + 125);
    if (full == NULL) {
    	fprintf(stderr,"[-] FATAL: Allocating Memory failed!\n");
    	exit(-1);
    	}
    
    strcpy(full,"");
    
    buf = (char *)malloc(4096);
    if (buf == NULL) {
    	fprintf(stderr,"[-] Couldn't allocate 4096 bytes ...\n");
    	exit(-1);
    	}
    
    while (1) {
    
    	tmp = recv(cliefd,buf,4096 - 1,0);
    	if (tmp == -1 || tmp == 0) {
    		free(buf);
    		break;
    		}
    	buf[tmp] = '\0';
    
    	strncat(full,buf,strlen(buf));
    	}
    char **buf_split;
    
    buf_split = split_('\n',full);
    
    free(full);
    
    char **user_pass;
    
    user_pass = split_(' ',buf_split[0]);
    
    safe_copy(current_user,user_pass[0],_SMALL_CHAR);
    
    char **final;
    final = split_(' ',buf_split[1]);
    
    if (client_routine_(cliefd,(const char **)final) == -1) {
    	send(cliefd,"QUERRY NOT OK\n",strlen("QUERRY NOT OK\n"),0);
    	free(final);
    	free(user_pass);
    	free(buf_split);
    	return (-1);
    	}
    
    free(final);
    free(user_pass);
    free(buf_split);
    return 0;
    }
    
    
    int client_routine_(SOCKET cliefd,const char **buf_split) {
    
    int tmp = 0;
    
    #ifdef DEBUG
    printf("[!] Starting Client routine [%i]\n",split_nr);
    fflush(stdout);
    for (tmp = 0;tmp <= split_nr;tmp++) {
    printf("\"%s\":%i\n",buf_split[tmp],tmp); }
    #endif
    
    
    int tmp2 = 0;
    char *tmp_buf;
    
    
    if (strcmp(buf_split[0],"ADD")==0) {
    	if (split_nr > 2) {
    		if (strcmp(buf_split[1],"USER")==0) {
    			printf("arguments: \"%s\":\"%s\"\n",buf_split[2],buf_split[3]);
    			tmp = mysql_register_user_((const char *)buf_split[2],(const char*)buf_split[3]);
    [.......]

    I'm trying to programm cross-platform.

    Compiling with
    Code:
    gcc (GCC) 4.1.2 20060613 (prerelease) (Debian 4.1.1-5)
    Linux inSan3 2.6.16.15 #3 PREEMPT i686 GNU/Linux
    Linux Debian 3.1 testing
    mysql  Ver 14.12 Distrib 5.0.22, for pc-linux-gnu (i486) using readline 5.1
    /usr/lib/libmysqlclient.so.15
    Compiling:
    Code:
    gcc -c main.c -o main.o -Wall
    gcc -c proto.c -o proto.o -Wall
    gcc -c sql.c -o sql.o -Wall
    gcc -c inet.c -o inet.o -Wall
    gcc -c globals.c -o globals.o -Wall
    gcc -c sql_actions.c -o sql_actions.o -Wall
    gcc -c parse_opts.c -o parse_opts.o -Wall
    gcc -c sync.c -o sync.o -Wall
    gcc -o ksd main.o proto.o sql.o inet.o globals.o sql_actions.o parse_opts.o sync.o -L/usr/lib/mysql -lmysqlclient -Wall
    GDB tells me:
    Code:
    [... i am sending "ADD USER test whatever" ...]
    [...]
    "ADD":0
    "USER":1
    "test":2
    "d9301das342193das890h":3
    arguments: "test":"d9301das342193das890h"
    registering user
    "test":"d9301das342193das890"
    
    Program received signal SIGSEGV, Segmentation fault.
    [Switching to Thread -1212918080 (LWP 5963)]
    0xb7d6f550 in mysql_send_query () from /usr/lib/libmysqlclient.so.15
    (gdb) backtrace
    #0  0xb7d6f550 in mysql_send_query () from /usr/lib/libmysqlclient.so.15
    #1  0xb7d6f630 in mysql_real_query () from /usr/lib/libmysqlclient.so.15
    #2  0x0804c6da in mysql_register_user_ ()
    #3  0x0804a89b in client_routine_ ()
    #4  0x0804bfcf in _start_client ()
    #5  0x0804b934 in get_client_sender_ ()
    #6  0x0804b6a6 in start_select ()
    #7  0x0804c0e2 in inet_setup_ ()
    #8  0x0804907a in main ()
    (gdb)
    Valgrind:
    Code:
    [... i am sending "ADD USER test whatever" ... ]
    registering user
    [...]
    "test":"d9301das342193das890"
    [...]
    ==5985== Process terminating with default action of signal 11 (SIGSEGV)
    ==5985==  Bad permissions for mapped region at address 0x40003A4
    ==5985==    at 0x409856F: mysql_send_query (in /usr/lib/libmysqlclient.so.15.0.0)
    ==5985==    by 0x409862F: mysql_real_query (in /usr/lib/libmysqlclient.so.15.0.0)
    ==5985==    by 0x804C6D9: mysql_register_user_ (in /home/user/programming/kolashare/ksd/src/ksd)
    ==5985==    by 0x804A89A: client_routine_ (in /home/user/programming/kolashare/ksd/src/ksd)
    ==5985==    by 0x804BFCE: _start_client (in /home/user/programming/kolashare/ksd/src/ksd)
    ==5985==    by 0x804B933: get_client_sender_ (in /home/user/programming/kolashare/ksd/src/ksd)
    ==5985==    by 0x804B6A5: start_select (in /home/user/programming/kolashare/ksd/src/ksd)
    ==5985==    by 0x804C0E1: inet_setup_ (in /home/user/programming/kolashare/ksd/src/ksd)
    ==5985==    by 0x8049079: main (in /home/user/programming/kolashare/ksd/src/ksd)
    ==5985== 
    ==5985== ERROR SUMMARY: 64 errors from 33 contexts (suppressed: 23 from 1)
    ==5985== malloc/free: in use at exit: 430,594 bytes in 42 blocks.
    ==5985== malloc/free: 133 allocs, 91 frees, 473,121 bytes allocated.
    ==5985== For counts of detected errors, rerun with: -v
    ==5985== searching for pointers to 42 not-freed blocks.
    ==5985== checked 618,308 bytes.
    ==5985== 
    ==5985== LEAK SUMMARY:
    ==5985==    definitely lost: 19,725 bytes in 11 blocks.
    ==5985==      possibly lost: 8,199 bytes in 1 blocks.
    ==5985==    still reachable: 402,670 bytes in 30 blocks.
    ==5985==         suppressed: 0 bytes in 0 blocks.
    ==5985== Use --leak-check=full to see details of leaked memory.
    segmentation fault
    I've checked
    - whether the SQL-Querry is OK ( it is )
    - whether Variables are OK ( they are ... i'm printf them )
    - whether it works with mysql_send_query ( no it doesn't )

    Again: It's strange: If i call the function in main() i don't get any errors.
    It looks like mysql_real_query calls mysql_send_query and this causes the segmentation fault.

    Thanks reading through this all,

    *disturbing*

    and a big thanks for helping me,

    Kolazomai
    Last edited by Kolazomai; 08-17-2006 at 11:43 AM. Reason: Change string to string_

  2. #2
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,175
    Now that's how you ask a question! Can we sticky this thing?

    I just wish I knew the answer.
    If you understand what you're doing, you're not learning anything.

  3. #3
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,262
    I'm not sure if this is it, but you shouldn't really call variables 'string' - that's a type in C ... String would be better, IMO

  4. #4
    Registered User Kolazomai's Avatar
    Join Date
    Aug 2006
    Posts
    12
    Quote Originally Posted by twomers
    I'm not sure if this is it, but you shouldn't really call variables 'string' - that's a type in C ... String would be better, IMO
    Done (and edited) . Nothing changed, Problem's still there.

  5. #5
    Registered User Kolazomai's Avatar
    Join Date
    Aug 2006
    Posts
    12
    Quote Originally Posted by itsme86
    Now that's how you ask a question! Can we sticky this thing?

    I just wish I knew the answer.
    Thanks

  6. #6
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,175
    Quote Originally Posted by twomers
    I'm not sure if this is it, but you shouldn't really call variables 'string' - that's a type in C ... String would be better, IMO
    string isn't a type in C, only in C++. However, I believe symbols that begin with str are reserved for the implementation and shouldn't be used in programs.
    If you understand what you're doing, you're not learning anything.

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I'd suggest checking your return values:
    Code:
    snprintf(tmp_qry,_STD_SQL_CHAR - 1,
    		"INSERT INTO %s (username,password,uploads,downloads,rating,nr_of_ratings,"
    		"names_of_guys_ive_rated)"
    		" VALUES ('%s','%s',0,0,0.00,0,'%s')",
    		_USER_TABLE_NAME,username,password,username);
    Also, try printing this out, as a debug step, before calling the function. Print, flush. To make sure what you think you're passing is really what you're passing.


    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    I prefer a standalone compileable example, otherwise I'm probably just ........ing in the wind. But here are some things that stand out to me.
    Code:
    for (tmp = 0;tmp <= strlen(string_);tmp++) {
    It's generally a red flag to me to go possibly one past the end -- or in this case to include the null terminator as well as the rest of the string. And using strlen(string_) as part of the condition is a performance eater.
    Code:
    char **ret;
    ret = (char **)malloc(nr_of_split_chars * sizeof(*ret));
    This makes it look like the bastard child C/C++, being neither C nor C++ and thus more difficult to deal with on either side.
    Code:
    for (tmp = 0;tmp <= nr_of_split_chars;tmp++) {
    Again, the usual idiom is for(i=0;i<N;++i). So another red flag goes up.
    Code:
    char *full;
    int tmp = 0;
    
    
    full = (char *)malloc(sizeof(char) * sizeof(struct ks_upload) + 25 + 125);
    if (full == NULL) {
    	fprintf(stderr,"[-] FATAL: Allocating Memory failed!\n");
    	exit(-1);
    	}
    
    strcpy(full,"");
    Again the casting, but the superfluous sizeof(char) (always 1) and the magic numbers are turn-offs. And so is a non-portable exit code.

    [aside]Stuff like that and the missing bits of code (other functions called), and such really lead me to give it a thumbs down as an example -- or to more fairly state -- "I'm glad I don't have to debug this".[/aside] But given the segmentation fault I might speculate that you may be attempting to write to memory you can't write to, such as a string literal or by having gone beyond array bounds.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  9. #9
    Registered User Kolazomai's Avatar
    Join Date
    Aug 2006
    Posts
    12
    Quote Originally Posted by quzah
    I'd suggest checking your return values:
    Code:
    snprintf(tmp_qry,_STD_SQL_CHAR - 1,
    		"INSERT INTO %s (username,password,uploads,downloads,rating,nr_of_ratings,"
    		"names_of_guys_ive_rated)"
    		" VALUES ('%s','%s',0,0,0.00,0,'%s')",
    		_USER_TABLE_NAME,username,password,username);
    Also, try printing this out, as a debug step, before calling the function. Print, flush. To make sure what you think you're passing is really what you're passing.


    Quzah.

    I don't even get to this point. As you can see in the output, everything seems to work right until mysql_real_query( ...

    I'm very sure (!) that all my arguments of mysql_real_query are OK and right ( printed them aswell ).

    I'm passing:
    Code:
    SELECT * FROM ks_users WHERE username='test'
    Return code of snprintf:
    Code:
    44
    Strlen of tmp_qry:
    Code:
    44
    Hex:
    Doesn't show special signs or chars.

    I prefer a standalone compileable example, otherwise I'm probably just ........ing in the wind. But here are some things that stand out to me.
    Code:

    for (tmp = 0;tmp <= strlen(string_);tmp++) {

    It's generally a red flag to me to go possibly one past the end -- or in this case to include the null terminator as well as the rest of the string. And using strlen(string_) as part of the condition is a performance eater.
    Code:

    char **ret;
    ret = (char **)malloc(nr_of_split_chars * sizeof(*ret));

    This makes it look like the bastard child C/C++, being neither C nor C++ and thus more difficult to deal with on either side.
    Code:

    for (tmp = 0;tmp <= nr_of_split_chars;tmp++) {

    Again, the usual idiom is for(i=0;i<N;++i). So another red flag goes up.
    Code:

    char *full;
    int tmp = 0;


    full = (char *)malloc(sizeof(char) * sizeof(struct ks_upload) + 25 + 125);
    if (full == NULL) {
    fprintf(stderr,"[-] FATAL: Allocating Memory failed!\n");
    exit(-1);
    }

    strcpy(full,"");

    Again the casting, but the superfluous sizeof(char) (always 1) and the magic numbers are turn-offs. And so is a non-portable exit code.



    [aside]Stuff like that and the missing bits of code (other functions called), and such really lead me to give it a thumbs down as an example -- or to more fairly state -- "I'm glad I don't have to debug this".[/aside] But given the segmentation fault I might speculate that you may be attempting to write to memory you can't write to, such as a string literal or by having gone beyond array bounds.
    Ok. Please tell me, how to do better

    I would like to safe performance, so i've chosen malloc many times instead of choosing the "normal" way of declaration. I can't use a "static char ret[nr_of_split_chars][1024];" cause it's not static then ... If i declar the variable, that should be changed, and put it as argument, i , again, don't know, how big it'll be. I don't want to use strtok, cause i made bad experiences with it ( you can't use strtok twice at the same time ).

    Don't think, i'll get problems with "[...]<= strlen([...]". It works well.

    Problem is already not solved and it's that strange. Why does it makes me an error, although
    Code:
    "snprintf(tmp_qry,..." was executed well ...
    the mysql_real_query is OK ...
    i can call it "native" and/or with a split_-callback-char as made in the context and it does work ...
    ??

    Ok, there is a segmentation fault.

    But why ? This doesn't make sense ... >.<

    Thanks for the answers,

    Kolazomai
    Last edited by Kolazomai; 08-17-2006 at 08:14 AM.

  10. #10
    Registered User Kolazomai's Avatar
    Join Date
    Aug 2006
    Posts
    12

    Open Source

    Hi,

    I prefer a standalone compileable example, otherwise I'm probably just ........ing in the wind. But here are some things that stand out to me.
    Click here to download the current Source-Code ( ca. 3200 lines ). Attention: Not tested on Windows. You need MySQL-Devels ( /usr/include/mysql/mysql.h ).
    Code:
    tar xfz kolashare.tar.gz
    cd src
    make
    ./ksd
    I'll publish it under the GPL after releasing a stable Version. Now please don't be angry with me writing Copyrights to my Sources

    Test my Problem with Executing this Python-Script:
    Code:
    #!/usr/bin/python
    import socket
    x = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    
    x.connect(('localhost',7961))
    
    x.send("register None\nADD USER test d9301das342193das890\n\n")
    
    while 1:
            data = x.recv(1024)
            print data
            if data == "":
                    break
    Or just send a
    "register None\nADD USER whatever whatever\n\n".

    Hoping for help,

    Kolazomai
    Last edited by Kolazomai; 08-18-2006 at 07:31 AM.

  11. #11
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    Quote Originally Posted by Kolazomai
    Click here to download the current Source-Code ( ca. 3200 lines ).
    My point was rather the opposite: instead of asking someone to debug your entire source, create a separate standalone compileable version -- preferably a single file -- with only relevant code and inputs, and preferably standard functions. Typically one solves the problem by the time this is finished.

    Shorter version: feed your function(s) a string (or whatever necessary inputs) which exhibit(s) the problem(s), and post what unexpected errors/output you get.

    Narrowing down the problem should be step 1 in debugging.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  12. #12
    Registered User Kolazomai's Avatar
    Join Date
    Aug 2006
    Posts
    12
    Quote Originally Posted by Dave_Sinkula
    My point was rather the opposite: instead of asking someone to debug your entire source, create a separate standalone compileable version -- preferably a single file -- with only relevant code and inputs, and preferably standard functions. Typically one solves the problem by the time this is finished.

    Shorter version: feed your function(s) a string (or whatever necessary inputs) which exhibit(s) the problem(s), and post what unexpected errors/output you get.

    Narrowing down the problem should be step 1 in debugging.
    Hi !

    Relevant Code is in the first Post.
    How about adding some "}" ?

    Sorry, but everything i've written before tells you, what you want to know. Or what are you missing ?

    I've also mentioned many times, that the Problem occours ONLY in the Context !!

    Isn't the Problem narrowed down enough ?!

    Sorry being that rude today.
    I would suppose you to read my Posts more properly, Dave_Sinkula...

    Thanks,

    Kolazomai

  13. #13
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by Kolazomai
    Hi !

    Relevant Code is in the first Post.
    How about adding some "}" ?

    Sorry, but everything i've written before tells you, what you want to know. Or what are you missing ?
    How about doing it your damn self? It's not an obligation we have to help you you know. Do it yourself. For that matter, just edit your posts and delete their contents.

    It only happens in context? Well then that means you ........ed your pointers up some place. If you can't duplicate it in a small example, then it means you ........ed up some place else and are just now encountering it.

    Grab a debugger and have fun.

    Oh and...
    Quote Originally Posted by Kolazomai
    Sorry being that rude today.
    I would suppose you to read my Posts more properly, Dave_Sinkula...
    I am not sorry for being rude, but I don't lie about it. I would suppose you to help someone help you if you really want help, instead of being a dumbass, Kolazomai...


    Quzah.
    Hope is the first step on the road to disappointment.

  14. #14
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,006
    >Relevant Code is in the first Post.

    Yes it is. And a good description of the problem as well. My apologies.

    >How about adding some "}" ?

    Huh?

    >Sorry, but everything i've written before tells you, what you want to know. Or what are you missing ?

    I can't compile it. I can't build it. I can't use my tools to assist you.

    >I've also mentioned many times, that the Problem occours ONLY in the Context !!

    Have you ever submitted a defect report? What someone in tech support usually says goes something like this: create a small, single-source program that only calls the minimum of functions to produce the error. Eliminate all the stuff that doesn't contribute to the potential bug. If it only takes three function calls to produce the error, can you create a simple file with only these three functions. This way your exact code that produces the error on your system can be built on my system to see if the same error is produced.

    Text descriptions are helpful, but exact code will get you the best results. And a full project is overkill.

    >Isn't the Problem narrowed down enough ?!

    Yes. If only I could take a post with just these couple functions in a main and attempt to compile it myself. I might even then have interest in downloading some MySQL stuff.

    >I would suppose you to read my Posts more properly, Dave_Sinkula...

    Point taken.

    Consider that this is a C forum, not a MySQL forum. Most of your replies will be regarding C rather than MySQL. Perhaps that would be reversed in a MySQL forum.

    Could something like this have demonstrated the problem more succinctly (commented-out stuff uncommented and properly filled with other necessities)?
    Code:
    #include <stdio.h>
    /* other headers */
    
    #define _USER_TABLE_NAME "ks_users"
    
    void foo(const char *text)
    {
       char username[4096], password[4096];
       if ( sscanf(text, "ADD USER %4095s %4095s", username, password) == 2 )
       {
          char tmp_qry[4096];
          snprintf(tmp_qry, sizeof tmp_qry,
                   "INSERT INTO %s (username,password,uploads,"
                   "downloads,rating,nr_of_ratings,"
                   "names_of_guys_ive_rated)"
                   " VALUES ('%s','%s',0,0,0.00,0,'%s')",
                   _USER_TABLE_NAME,username,password,username);
          puts(tmp_qry);
          /*
          if ( mysql_real_query(sql_conn.my,tmp_qry,strlen(tmp_qry)) != 0 ) /* BANG! */
          {
             return -1;
          }
          */
       }
    }
    
    int main(void)
    {
       foo("ADD USER myusername mypassword");
       return 0;
    }
    That was my meaning about "relevant code". But it's obvious my communication skills are lacking.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  15. #15
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,825
    > ret = (char **)malloc(nr_of_split_chars * sizeof(*ret));
    > for (tmp = 0;tmp <= nr_of_split_chars;tmp++)
    Until you learn that an N array is indexed from 0 to N-1 there is really no hope for you. STOP using <= in your array indexing loops.
    http://en.wikipedia.org/wiki/Fencepost_error

    This one mistake means you step off the end of your allocated memory for ret. After that, all bets are off as to how long your program lasts. Quite annoyingly, sometimes you can get away with it, but that's just a sucker move to lure you into thinking the program is OK.

    > strncat(full,buf,strlen(buf));
    Another major mistake. You carefully initialise the start of full with a \0 by doing a strcpy(full,""), but that only initialises the first character. The rest of the memory returned by malloc is uninitialised (could be anything). Unfortunately all your strncat() calls fail to maintain the \0. The first one will work, but following attempts to strncat() could write much further into full (perhaps even way past the end).
    If you really want to protect full from buffer overflow, you need (crudely)
    if ( strlen(full) + strlen(buf) < limit ) strcat(full,buff);

    > ==5985== definitely lost: 19,725 bytes in 11 blocks.
    char **final;
    final = split_(' ',buf_split[1]);
    free(final);
    Erm, you need to free(final[i]) for as many lines as you've stored, before you free(final)
    Your split function should return the number of splits it made, to make this possible.

    Oh, and what's with all the inline variable declarations and casting of malloc?
    Are you compiling this with a C++ compiler?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. MySQL libraries
    By csonx_p in forum C++ Programming
    Replies: 6
    Last Post: 10-02-2008, 03:23 AM
  2. mysql c api problems
    By rotis23 in forum C Programming
    Replies: 0
    Last Post: 10-07-2002, 05:15 AM
  3. OLE Clipboard :: Win32 API vs. MFC
    By kuphryn in forum Windows Programming
    Replies: 3
    Last Post: 08-11-2002, 06:57 PM
  4. strange errors...
    By endo in forum Windows Programming
    Replies: 3
    Last Post: 08-02-2002, 05:19 AM
  5. errors in class(urgent)
    By ayesha in forum C++ Programming
    Replies: 2
    Last Post: 11-10-2001, 06:51 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21