Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Segmentation fault (C & Mysql & unix) / 19 сообщений из 19, страница 1 из 1
31.05.2007, 08:13
    #34563109
chikanok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
Здраствуйте!
Подскажите пожалуйста что за ошибка и как лечится!
Вылетает при запуске мой программки. Прога конектится и делает запрос БД, выполняет mysql_store_result() и mysql_num_rows А после эта ошибка.
Далее прога должна в цикле выполнить mysql_fetch_row() и вывести результат,ну а после mysql_free_result и mysql_close.
Хех. А вот исходник:
Код: plaintext
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.
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h>
#include <sys/time.h>
#include <errno.h>


int main(int argc, char *argv[])
{
MYSQL_RES *res;
MYSQL_ROW row;
MYSQL *connection,mysql;
int state;
mysql_init(&mysql);
 printf("Init\n");
connection=mysql_real_connect(&mysql,"localhost","root","hex","mysql", 0 ,"/var/lib/mysql/mysql.sock", 0 );
if(connection==NULL){
	perror( mysql_error(&mysql));
	exit(errno);
}
 printf("Connected\n");
state=mysql_query(connection,"Select host,user,password from user;");
if (state!= 0 ){
	perror(mysql_error(connection));
	exit(errno);
}
 if(state!= 0 ){
   perror(mysql_error(connection));
   exit;
}
 res= mysql_store_result(connection);
 printf("Strok:%d\n",mysql_num_rows(res));
 while((row=mysql_fetch_row(res))!=NULL){
   printf("host:%s , name:%s ,pwd:%s",(row[ 0 ] ? row[ 0 ]:"NULL"),(row[ 1 ] ? row[ 1 ]:"NULL"),(row[ 2 ] ? row[ 2 ] :"NULL"));
}
 mysql_free_result(res);
 mysql_close(connection);

  return EXIT_SUCCESS;
}
...
Рейтинг: 0 / 0
31.05.2007, 08:36
    #34563140
blinded
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
Ну судя повсему должно быть
MYSQL_ROW* row;
убери двойноую обработку ошибки коннекта и ежели пишешь на С++ не юзай exit. только return
...
Рейтинг: 0 / 0
31.05.2007, 09:23
    #34563234
chikanok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
Ежели сделать так MYSQL_ROW* row то ошибка несовместимости типов!
Пишу на С.
...
Рейтинг: 0 / 0
31.05.2007, 09:34
    #34563256
blinded
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
Ну тогда не знаю, но проблема в том что в цикле идет обращение за пределы адресного пространства процесса.
...
Рейтинг: 0 / 0
31.05.2007, 09:58
    #34563336
chikanok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
Хмм. А мож косяк в библиотеке(libmysqlclient.so.15)???
Я засунул весь цикл в коментарии компильнул и таже ошибка, также после :
Код: plaintext
1.
res= mysql_store_result(connection);
 printf("Strok:%d\n",mysql_num_rows(res));

При первом запуске он немог найти библиотеку(libmysqlclient.so.15), ну я ему и дал библиотеку в /usr/lib
...
Рейтинг: 0 / 0
31.05.2007, 10:18
    #34563407
blinded
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
Ну я не пророк, через кабель не вижу. Бери gdb, поизучай core
gdb <имя программы> core
скажи bt он стек прокажет, ну а дальше там есть встроенный help - вперед и с песней
...
Рейтинг: 0 / 0
31.05.2007, 11:26
    #34563786
chikanok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
Методом тыка и удалением кода дошел вот до такого кода:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
int main(int argc, char *argv[])
{
MYSQL_RES *res;
MYSQL_ROW row;
MYSQL *connection,mysql;
int state;
return EXIT_SUCCESS;
}
Как бы это небыло смешно!!!
Но после добавления строки:
Код: plaintext
1.
mysql_init(&mysql);
Вылетает эта мифическая ошибка.
После последовал экспиримент:
Код: plaintext
1.
2.
printf("%d\n",mysql);
mysql_init(&mysql);
printf("%d\n",mysql);
Вывод:
Код: plaintext
1.
2.
3.
 25697 
 0 
Segmentation fault
хех. Фишка в том что ошибка вылетает не сразу, а через некоторое время или несколько операций.
тоесть косяк не в проге.
В тоже время прога "mysql" пользует туже библиотеку и вполне работает!
Как так? и что делать?
...
Рейтинг: 0 / 0
31.05.2007, 12:04
    #34564036
blinded
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
Что делать, что делать... Я тебе сказал возьми core файл в debugger и посмотри стек. Но скорее всего у тебя что-то не так с ининциализацией мускула, - после mysql_init mysql == 0
...
Рейтинг: 0 / 0
31.05.2007, 12:34
    #34564177
Анатолий Широков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
Все это похоже на то, что sizeof(MYSQL) в вашем коде отличен от того, который используется библиотекой, поскольку сам по себе mysql_init безобиден:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
MYSQL * STDCALL
mysql_init(MYSQL *mysql)
{
  if (mysql_server_init( 0 , NULL, NULL))
    return  0 ;
  if (!mysql)
  {
    if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL))))
      return  0 ;
    mysql->free_me= 1 ;
  }
  else
    bzero((char*) (mysql), sizeof(*(mysql)));
  mysql->options.connect_timeout= CONNECT_TIMEOUT;
  mysql->last_used_con= mysql->next_slave= mysql->master = mysql;
  mysql->charset=default_client_charset_info;
  strmov(mysql->net.sqlstate, not_error_sqlstate);
....
...
Рейтинг: 0 / 0
31.05.2007, 12:47
    #34564249
chikanok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
2 Анатолий Широков

И как такое вылечить?!
Встретил вот такой код :
Код: plaintext
1.
if(!mysql_init(&mysql)){ /*ОШИБКА */ } 
вкрутил к себе, сообщение об ошибке не вылетело!
А если так :
Код: plaintext
printf("%d\n",mysql_init(&mysql)); 
то выводит:
Код: plaintext
1.
2.
 - 1073745168 
free():invalid pointer 0x40183f68!
Segmentation fault
Что делать?
...
Рейтинг: 0 / 0
31.05.2007, 13:06
    #34564346
blinded
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
Анатолий ШироковВсе это похоже на то, что sizeof(MYSQL) в вашем коде отличен от того, который используется библиотекой, поскольку сам по себе mysql_init безобиден:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
MYSQL * STDCALL
mysql_init(MYSQL *mysql)
{
  if (mysql_server_init( 0 , NULL, NULL))
    return  0 ;
  if (!mysql)
  {
    if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL))))
      return  0 ;
    mysql->free_me= 1 ;
  }
  else
    bzero((char*) (mysql), sizeof(*(mysql)));
  mysql->options.connect_timeout= CONNECT_TIMEOUT;
  mysql->last_used_con= mysql->next_slave= mysql->master = mysql;
  mysql->charset=default_client_charset_info;
  strmov(mysql->net.sqlstate, not_error_sqlstate);
....

Исходя из приведенного кода, указатель перед первым вызовом mysql_init надо обнулить, А то в белый свет как в копейку
...
Рейтинг: 0 / 0
31.05.2007, 13:11
    #34564376
Zmeishe
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
// Если это так:
MYSQL * STDCALL
mysql_init(MYSQL *mysql)
{
  if (mysql_server_init( 0 , NULL, NULL))
    return  0 ;
  if (!mysql)
  {
    if (!(mysql=(MYSQL*) my_malloc(sizeof(*mysql),MYF(MY_WME | MY_ZEROFILL))))
...

Код: plaintext
1.
2.
//То почему надо делать так?
MYSQL *connection, mysql;
mysql_init(&mysql);

Код: plaintext
1.
2.
// А не вот так
MYSQL *connection, *mysql;
mysql_init(mysql);
???
...
Рейтинг: 0 / 0
31.05.2007, 13:49
    #34564605
blinded
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
и я и змей не правы. Скорее всего взят неправильный h файл не от этой версии, в бибилотеке размер структуры MYSQL больше чем для mainю И mysql_init разваливает стек.
Самое смешное что если работать не через автоматическую переменную, а использовать линамическую память, то все бы работало
Код: plaintext
1.
2.
MYSQL* mysql = mysql_init( 0 );
...
...
Рейтинг: 0 / 0
31.05.2007, 13:55
    #34564643
Zmeishe
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
Я бы всё-таки подождал пока он проверит этот наш обобщённый кусок.
Код: plaintext
1.
2.
MYSQL *mysql;
mysql = NULL;
mysql_init(mysql);
...
Рейтинг: 0 / 0
31.05.2007, 14:18
    #34564707
Анатолий Широков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
ZmeisheЯ бы всё-таки подождал пока он проверит этот наш обобщённый кусок.
Код: plaintext
1.
2.
MYSQL *mysql;
mysql = NULL;
mysql_init(mysql);


Что здесь проверять - здесь будет утечка памяти и mysql как была NULL так ей и останется.
В идеологии mysql_init, если вы передаете указатель, то должы его сохранить:

Код: plaintext
1.
mysql = mysql_init(mysql или NULL);

Если передаете адрес на стековую переменную, то нужно лишь проверить код возврата:

Код: plaintext
1.
2.
3.
4.
5.
MYSQL mysql;
if( mysql_init(&mysql) ) {
    return  1 ; // error
}

...
Рейтинг: 0 / 0
31.05.2007, 14:22
    #34564715
Анатолий Широков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
Ха, а слон-то на поверхности оказалася. Стек валится из-за того, что вы пытаетесь выводите структуру mysql, которая не является integer-ом, как integer, то есть следующий код и валит стек:

Код: plaintext
printf("%d\n",mysql);
...
Рейтинг: 0 / 0
31.05.2007, 14:28
    #34564729
blinded
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
Не-а, неправильно код возврата проверяешь!
Он в случае успеха возвращает указатель на MYSQL? аллокированную им или предоставленную программером, неудача - возврат 0
Причем в ситуации когда программер предоставляет предоставляет свой объект код возврат будет нормальным (!=0), поскольку дальше идет только инициализация полей структуры. Но вот ежели размеры структур разные то при инициализаци будет развален стек процесса и все пойдет кувырком
...
Рейтинг: 0 / 0
31.05.2007, 14:29
    #34564730
Анатолий Широков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
Да, я уже заметил, но суть это не меняет.
...
Рейтинг: 0 / 0
31.05.2007, 15:22
    #34564959
chikanok
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Segmentation fault (C & Mysql & unix)
Ух! Спасибо люди!
Надо было обнулить указатель mysql.
я сделал через bzero(&mysql,sizeof(&mysql));
и всё заработало!
Еще раз ОГРОМНОЕ СПАСИБО!!!
Значит тему можно закрывать!!!
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Segmentation fault (C & Mysql & unix) / 19 сообщений из 19, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]