1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-07 02:42:49 +03:00

DBUG update and fixes

Fixed net_read crash in debug version
This commit is contained in:
holzboote@googlemail.com
2013-07-15 10:47:05 +02:00
parent d698bdddb8
commit d6f3bb4c9f
13 changed files with 2186 additions and 1751 deletions

View File

@@ -21,34 +21,48 @@
extern "C" {
#endif
#if !defined(DBUG_OFF) && !defined(_lint)
extern int _db_on_,_no_db_;
extern FILE *_db_fp_;
extern char *_db_process_;
extern int _db_keyword_(const char *keyword);
extern void _db_setjmp_(void);
extern void _db_longjmp_(void);
extern void _db_push_(const char *control);
extern void _db_pop_(void);
extern void _db_enter_(const char *_func_,const char *_file_,uint _line_,
const char **_sfunc_,const char **_sfile_,
uint *_slevel_, char ***);
extern void _db_return_(uint _line_,const char **_sfunc_,const char **_sfile_,
uint *_slevel_);
extern void _db_pargs_(uint _line_,const char *keyword);
extern void _db_doprnt_ _VARARGS((const char *format,...));
extern void _db_dump_(uint _line_,const char *keyword,const char *memory,
uint length);
extern void _db_lock_file(void);
extern void _db_unlock_file(void);
#define DBUG_ENTER(a) const char *_db_func_, *_db_file_; uint _db_level_; \
char **_db_framep_; \
_db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_, \
&_db_framep_)
struct _db_stack_frame_ {
const char *func; /* function name of the previous stack frame */
const char *file; /* filename of the function of previous frame */
uint level; /* this nesting level, highest bit enables tracing */
struct _db_stack_frame_ *prev; /* pointer to the previous frame */
};
struct _db_code_state_;
extern my_bool _dbug_on_;
extern my_bool _db_keyword_(struct _db_code_state_ *, const char *, int);
extern int _db_explain_(struct _db_code_state_ *cs, char *buf, size_t len);
extern int _db_explain_init_(char *buf, size_t len);
extern int _db_is_pushed_(void);
extern void _db_setjmp_(void);
extern void _db_longjmp_(void);
extern void _db_process_(const char *name);
extern void _db_push_(const char *control);
extern void _db_pop_(void);
extern void _db_set_(const char *control);
extern void _db_set_init_(const char *control);
extern void _db_enter_(const char *_func_, const char *_file_, uint _line_,
struct _db_stack_frame_ *_stack_frame_);
extern void _db_return_(uint _line_, struct _db_stack_frame_ *_stack_frame_);
extern void _db_pargs_(uint _line_,const char *keyword);
extern void _db_doprnt_ _VARARGS((const char *format,...));
extern void _db_dump_(uint _line_,const char *keyword,
const unsigned char *memory, size_t length);
extern void _db_end_(void);
extern void _db_lock_file_(void);
extern void _db_unlock_file_(void);
extern FILE *_db_fp_(void);
extern void _db_flush_();
extern const char* _db_get_func_(void);
/*
#define DBUG_ENTER(a) struct _db_stack_frame_ _db_stack_frame_; \
_db_enter_ (a,__FILE__,__LINE__,&_db_stack_frame_)
#define DBUG_LEAVE \
(_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_))
#define DBUG_RETURN(a1) {DBUG_LEAVE; return(a1);}
#define DBUG_RETURN(a1) do {DBUG_LEAVE; return(a1);} while(0)
#define DBUG_VOID_RETURN {DBUG_LEAVE; return;}
#define DBUG_END() _db_end_ ()
#define DBUG_EXECUTE(keyword,a1) \
{if (_db_on_) {if (_db_keyword_ (keyword)) { a1 }}}
#define DBUG_PRINT(keyword,arglist) \
@@ -66,10 +80,49 @@ extern void _db_unlock_file(void);
#define DEBUGGER_ON _no_db_=0
#define DBUG_LOCK_FILE { _db_lock_file(); }
#define DBUG_UNLOCK_FILE { _db_unlock_file(); }
#define DBUG_ASSERT(A) assert(A) */
#define DBUG_ENTER(a) struct _db_stack_frame_ _db_stack_frame_; \
_db_enter_ (a,__FILE__,__LINE__,&_db_stack_frame_)
#define DBUG_LEAVE _db_return_ (__LINE__, &_db_stack_frame_)
#define DBUG_RETURN(a1) do {DBUG_LEAVE; return(a1);} while(0)
#define DBUG_VOID_RETURN do {DBUG_LEAVE; return;} while(0)
#define DBUG_EXECUTE(keyword,a1) \
do {if (_db_keyword_(0, (keyword), 0)) { a1 }} while(0)
#define DBUG_EXECUTE_IF(keyword,a1) \
do {if (_db_keyword_(0, (keyword), 1)) { a1 }} while(0)
#define DBUG_EVALUATE(keyword,a1,a2) \
(_db_keyword_(0,(keyword), 0) ? (a1) : (a2))
#define DBUG_EVALUATE_IF(keyword,a1,a2) \
(_db_keyword_(0,(keyword), 1) ? (a1) : (a2))
#define DBUG_PRINT(keyword,arglist) \
do {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;} while(0)
#define DBUG_PUSH(a1) _db_push_ (a1)
#define DBUG_POP() _db_pop_ ()
#define DBUG_SET(a1) _db_set_ (a1)
#define DBUG_SET_INITIAL(a1) _db_set_init_ (a1)
#define DBUG_PROCESS(a1) _db_process_(a1)
#define DBUG_FILE _db_fp_()
#define DBUG_SETJMP(a1) (_db_setjmp_ (), setjmp (a1))
#define DBUG_LONGJMP(a1,a2) (_db_longjmp_ (), longjmp (a1, a2))
#define DBUG_DUMP(keyword,a1,a2) _db_dump_(__LINE__,keyword,a1,a2)
#define DBUG_END() _db_end_ ()
#define DBUG_LOCK_FILE _db_lock_file_()
#define DBUG_UNLOCK_FILE _db_unlock_file_()
#define DBUG_ASSERT(A) assert(A)
#define DBUG_EXPLAIN(buf,len) _db_explain_(0, (buf),(len))
#define DBUG_EXPLAIN_INITIAL(buf,len) _db_explain_init_((buf),(len))
#define DEBUGGER_OFF do { _dbug_on_= 0; } while(0)
#define DEBUGGER_ON do { _dbug_on_= 1; } while(0)
#ifndef _WIN32
#define DBUG_ABORT() (_db_flush_(), abort())
#else
#define DBUG_ABORT() (_db_flush_(), exit(3))
#endif
#else /* No debugger */
#define DBUG_ENTER(a1)
#define DBUG_END() {}
#define DBUG_RETURN(a1) return(a1)
#define DBUG_VOID_RETURN return
#define DBUG_EXECUTE(keyword,a1) {}

View File

@@ -326,13 +326,6 @@ typedef unsigned short ushort;
#define DBUG_OFF
#endif
#include <dbug.h>
#ifndef DBUG_OFF
#define dbug_assert(A) assert(A)
#else
#define dbug_assert(A)
#endif
#define MIN_ARRAY_SIZE 0 /* Zero or One. Gcc allows zero*/
#define ASCII_BITS_USED 8 /* Bit char used */
#define NEAR_F /* No near function handling */
@@ -1061,6 +1054,13 @@ do { doubleget_union _tmp; \
#define SO_EXT ".so"
#endif
#include <dbug.h>
#ifndef DBUG_OFF
#define dbug_assert(A) assert(A)
#else
#define dbug_assert(A)
#endif
#ifdef HAVE_DLOPEN
#ifdef _WIN32
#define dlsym(lib, name) GetProcAddress((HMODULE)lib, name)

View File

@@ -551,6 +551,7 @@ struct st_my_thread_var
};
extern struct st_my_thread_var *_my_thread_var(void) __attribute__ ((const));
extern void **my_thread_var_dbug();
#define my_thread_var (_my_thread_var())
#define my_errno my_thread_var->thr_errno

View File

@@ -70,6 +70,7 @@ void vio_reset(Vio* vio, enum enum_vio_type type,
* as read(2) and write(2).
*/
size_t vio_read(Vio* vio, gptr buf, size_t size);
my_bool vio_read_peek(Vio *vio, size_t *bytes);
size_t vio_write(Vio* vio, const gptr buf, size_t size);
/*
* Whenever the socket is set to blocking mode or not.

File diff suppressed because it is too large Load Diff

View File

@@ -702,11 +702,8 @@ append_wild(char *to, char *end, const char *wild)
void STDCALL mysql_debug_end()
{
#ifndef DBUG_OFF
if (_db_on_)
{
DEBUGGER_OFF;
DBUG_POP();
}
DEBUGGER_OFF;
DBUG_POP();
#endif
}
@@ -715,8 +712,6 @@ mysql_debug(const char *debug __attribute__((unused)))
{
#ifndef DBUG_OFF
char *env;
if (_db_on_)
return; /* Already using debugging */
if (debug)
{
DEBUGGER_ON;
@@ -1193,7 +1188,7 @@ MYSQL_DATA *mthd_my_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
result->rows++;
if (!(cur= (MYSQL_ROWS*) alloc_root(&result->alloc,
sizeof(MYSQL_ROWS))) ||
!(cur->data= ((MYSQL_ROW)
!(cur->data= ((MYSQL_ROW)
alloc_root(&result->alloc,
(fields+1)*sizeof(char *)+pkt_len))))
{
@@ -1209,11 +1204,11 @@ MYSQL_DATA *mthd_my_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
{
if ((len=(ulong) net_field_length(&cp)) == NULL_LENGTH)
{ /* null field */
cur->data[field] = 0;
cur->data[field] = 0;
}
else
{
cur->data[field] = to;
cur->data[field] = to;
if (len > (ulong) (end_to - to))
{
free_rows(result);
@@ -1565,8 +1560,9 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql,const char *host, const char *user,
if (hPipe == INVALID_HANDLE_VALUE)
#endif
{
struct addrinfo hints, *save_res, *res= 0;
struct addrinfo hints, *save_res= 0, *res= 0;
char server_port[NI_MAXSERV];
int gai_rc;
int rc;
unix_socket=0; /* This is not used */
@@ -1575,6 +1571,7 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql,const char *host, const char *user,
if (!host)
host=LOCAL_HOST;
sprintf(host_info=buff,ER(CR_TCP_CONNECTION),host);
bzero(&server_port, NI_MAXSERV);
DBUG_PRINT("info",("Server name: '%s'. TCP sock: %d", host,port));
@@ -1587,30 +1584,32 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql,const char *host, const char *user,
hints.ai_socktype= SOCK_STREAM;
/* Get the address information for the server using getaddrinfo() */
if ((rc= getaddrinfo(host, server_port, &hints, &res)))
gai_rc= getaddrinfo(host, server_port, &hints, &res);
if (gai_rc != 0)
{
my_set_error(mysql, CR_UNKNOWN_HOST, SQLSTATE_UNKNOWN,
ER(CR_UNKNOWN_HOST), host, rc);
ER(CR_UNKNOWN_HOST), host, gai_rc);
goto error;
}
/* res is a linked list of addresses. If connect to an address fails we will not return
an error, instead we will try the next address */
for (save_res= res; save_res; save_res= save_res->ai_next)
{
if ((sock= (my_socket)socket(save_res->ai_family,
save_res->ai_socktype,
save_res->ai_protocol)) == SOCKET_ERROR)
{
sock= socket(save_res->ai_family, save_res->ai_socktype,
save_res->ai_protocol);
if (sock == SOCKET_ERROR)
/* we do error handling after for loop only for last call */
continue;
if (!(net->vio= vio_new(sock, VIO_TYPE_TCPIP, FALSE)))
{
my_set_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate, 0);
closesocket(sock);
freeaddrinfo(res);
goto error;
}
if (!(rc= connect2(sock, save_res->ai_addr, save_res->ai_addrlen,
mysql->options.connect_timeout)))
mysql->options.connect_timeout)))
break; /* success! */
vio_delete(mysql->net.vio);
@@ -1629,7 +1628,7 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql,const char *host, const char *user,
if (rc)
{
my_set_error(mysql, CR_CONN_HOST_ERROR, SQLSTATE_UNKNOWN, ER(CR_CONN_HOST_ERROR),
unix_socket, socket_errno);
host, rc);
goto error;
}
}
@@ -2031,6 +2030,7 @@ static void mysql_close_options(MYSQL *mysql)
my_free(mysql->options.extension->default_auth, MYF(MY_ALLOW_ZERO_PTR));
my_free((gptr)mysql->options.extension->db_driver, MYF(MY_ALLOW_ZERO_PTR));
}
my_free((gptr)mysql->options.extension, MYF(MY_ALLOW_ZERO_PTR));
/* clear all pointer */
memset(&mysql->options, 0, sizeof(mysql->options));
}

View File

@@ -162,10 +162,10 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
#endif
}
#ifdef THREAD
pthread_mutex_destroy(&THR_LOCK_keycache);
pthread_mutex_destroy(&THR_LOCK_malloc);
pthread_mutex_destroy(&THR_LOCK_open);
DBUG_POP(); /* Must be done before my_thread_end */
pthread_mutex_destroy(&THR_LOCK_net);
DBUG_END(); /* Must be done before my_thread_end */
my_thread_end();
my_thread_global_end();
#endif
@@ -244,7 +244,6 @@ static void my_win_init(void)
/* Crea la stringa d'ambiente */
setEnvString(EnvString, NameValueBuffer, DataValueBuffer) ;
/* Inserisce i dati come variabili d'ambiente */
my_env=strdup(EnvString); /* variable for putenv must be allocated ! */
putenv(my_env) ;

View File

@@ -30,9 +30,8 @@ pthread_key(struct st_my_thread_var*, THR_KEY_mysys);
#else
pthread_key(struct st_my_thread_var, THR_KEY_mysys);
#endif /* USE_TLS */
pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache,
THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap,
THR_LOCK_net, THR_LOCK_charset;
pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,
THR_LOCK_lock, THR_LOCK_net, THR_LOCK_mysys;
#ifdef HAVE_OPENSSL
pthread_mutex_t LOCK_ssl_config;
#endif
@@ -48,6 +47,7 @@ pthread_mutexattr_t my_fast_mutexattr;
#ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
pthread_mutexattr_t my_errchk_mutexattr;
#endif
my_bool THR_KEY_mysys_initialized= FALSE;
/* FIXME Note. TlsAlloc does not set an auto destructor, so
the function my_thread_global_free must be called from
@@ -69,18 +69,14 @@ my_bool my_thread_global_init(void)
pthread_mutexattr_setkind_np(&my_errchk_mutexattr,
PTHREAD_MUTEX_ERRORCHECK_NP);
#endif
THR_KEY_mysys_initialized= TRUE;
#ifdef HAVE_OPENSSL
pthread_mutex_init(&LOCK_ssl_config,MY_MUTEX_INIT_FAST);
#endif
pthread_mutex_init(&THR_LOCK_malloc,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_open,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_keycache,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_isam,MY_MUTEX_INIT_SLOW);
pthread_mutex_init(&THR_LOCK_myisam,MY_MUTEX_INIT_SLOW);
pthread_mutex_init(&THR_LOCK_heap,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_charset,MY_MUTEX_INIT_FAST);
#ifdef _WIN32
/* win_pthread_init(); */
#endif
@@ -163,6 +159,7 @@ void my_thread_end(void)
#if !defined(DBUG_OFF)
if (tmp->dbug)
{
DBUG_POP();
free(tmp->dbug);
tmp->dbug=0;
}
@@ -183,7 +180,6 @@ struct st_my_thread_var *_my_thread_var(void)
struct st_my_thread_var *tmp=
my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
#if defined(USE_TLS)
/* This can only happen in a .DLL */
if (!tmp)
{
my_thread_init();
@@ -230,6 +226,22 @@ const char *my_thread_name(void)
}
return tmp->name;
}
extern void **my_thread_var_dbug()
{
struct st_my_thread_var *tmp;
/*
Instead of enforcing DBUG_ASSERT(THR_KEY_mysys_initialized) here,
which causes any DBUG_ENTER and related traces to fail when
used in init / cleanup code, we are more tolerant:
using DBUG_ENTER / DBUG_PRINT / DBUG_RETURN
when the dbug instrumentation is not in place will do nothing.
*/
if (! THR_KEY_mysys_initialized)
return NULL;
tmp= _my_thread_var();
return tmp && tmp->initialized ? &tmp->dbug : 0;
}
#endif /* DBUG_OFF */
#endif /* THREAD */

View File

@@ -174,22 +174,19 @@ static my_bool net_realloc(NET *net, size_t length)
DBUG_RETURN(0);
}
#if !defined(DBUG_OFF1) || defined(USE_NET_CLEAR)
static int net_check_if_data_available(Vio *vio)
#ifdef DEBUG_SOCKET
static ssize_t net_check_if_data_available(Vio *vio)
{
my_socket sd= vio->sd;
fd_set sockset;
struct timeval tv;
int rc;
ssize_t length= 0;
FD_ZERO(&sockset);
FD_SET(sd, &sockset);
memset(&tv, 0, sizeof(tv));
rc= select((int)(sd + 1), &sockset, NULL, NULL, &tv);
if (rc <= 0)
if (vio->type != VIO_TYPE_SOCKET &&
vio->type != VIO_TYPE_TCPIP)
return 0;
return FD_ISSET(sd, &sockset);
if (vio_read_peek(vio, (size_t *)&length))
return -1;
return length;
}
#endif
@@ -197,45 +194,12 @@ static int net_check_if_data_available(Vio *vio)
void net_clear(NET *net)
{
#if !defined(DBUG_OFF1) || defined(USE_NET_CLEAR)
int available= 0;
size_t count; /* One may get 'unused' warning */
bool is_blocking=vio_is_blocking(net->vio);
DBUG_ENTER("net_clear");
DBUG_ENTER("net_clear");
while ((available= net_check_if_data_available(net->vio)) > 0)
{
if ((long)(count= vio_read(net->vio, (char *)net->buff, net->max_packet)) > 0)
{
DBUG_PRINT("info",("skipped %d bytes from file: %s",
count,vio_description(net->vio)));
}
else
{
DBUG_PRINT("info", ("socket disconnected"));
net->error= 2;
break;
}
}
if (available == -1)
{
if (is_blocking)
vio_blocking(net->vio, FALSE);
if (!vio_is_blocking(net->vio)) /* Safety if SSL */
{
while ( (count = vio_read(net->vio, (char*) (net->buff),
net->max_packet)) > 0)
DBUG_PRINT("info",("skipped %d bytes from file: %s",
count,vio_description(net->vio)));
if (is_blocking)
vio_blocking(net->vio, TRUE);
}
}
#else
DBUG_ENTER("net_clear");
#ifdef DEBUG_SOCKET
DBUG_ASSERT(net_check_if_data_available(net->vio) < 2);
#endif
net->compress_pkt_nr= net->pkt_nr=0; /* Ready for new command */
net->write_pos=net->buff;
DBUG_VOID_RETURN;

View File

@@ -1,15 +1,15 @@
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
@@ -61,7 +61,7 @@
/*
* Memory sub-system, written by Bjorn Benson
Fixed to use my_sys scheme by Michael Widenius
Fixed to use my_sys scheme by Michael Widenius
*/
#ifndef SAFEMALLOC
@@ -82,10 +82,10 @@ ulonglong safemalloc_mem_limit = ~(ulonglong)0;
#define uDataSize tInt._uDataSize
#define lSpecialValue tInt._lSpecialValue
/* Static functions prototypes */
/* Static functions prototypes */
static int check_ptr(const char *where, unsigned char *ptr, const char *sFile,
uint uLine);
uint uLine);
static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine);
/*
@@ -97,11 +97,11 @@ static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine);
*/
#define ALLOC_VAL (uchar) 0xA5 /* NEW'ed memory is filled with this */
/* value so that references to it will */
/* end up being very strange. */
/* value so that references to it will */
/* end up being very strange. */
#define FREE_VAL (uchar) 0x8F /* FREE'ed memory is filled with this */
/* value so that references to it will */
/* also end up being strange. */
/* value so that references to it will */
/* also end up being strange. */
#define MAGICKEY 0x14235296 /* A magic value for underrun key */
#define MAGICEND0 0x68 /* Magic values for overrun keys */
@@ -109,11 +109,11 @@ static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine);
#define MAGICEND2 0x7A /* " */
#define MAGICEND3 0x15 /* " */
/* Warning: do not change the MAGICEND? values to */
/* something with the high bit set. Various C */
/* compilers (like the 4.2bsd one) do not do the */
/* sign extension right later on in this code and */
/* you will get erroneous errors. */
/* Warning: do not change the MAGICEND? values to */
/* something with the high bit set. Various C */
/* compilers (like the 4.2bsd one) do not do the */
/* sign extension right later on in this code and */
/* you will get erroneous errors. */
/*
@@ -123,87 +123,87 @@ static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine);
gptr _mymalloc (size_t uSize, const char *sFile, uint uLine, myf MyFlags)
{
struct remember *pTmp;
DBUG_ENTER("_mymalloc");
DBUG_PRINT("enter",("Size: %u",uSize));
struct remember *pTmp;
DBUG_ENTER("_mymalloc");
DBUG_PRINT("enter",("Size: %u",uSize));
if (!sf_malloc_quick)
(void) _sanity (sFile, uLine);
if (!sf_malloc_quick)
(void) _sanity (sFile, uLine);
if(uSize + lCurMemory > safemalloc_mem_limit)
pTmp = 0;
else
/* Allocate the physical memory */
pTmp = (struct remember *) malloc (
sizeof (struct irem) /* remember data */
+ sf_malloc_prehunc
+ uSize /* size requested */
+ 4 /* overrun mark */
+ sf_malloc_endhunc
);
if(uSize + lCurMemory > safemalloc_mem_limit)
pTmp = 0;
else
/* Allocate the physical memory */
pTmp = (struct remember *) malloc (
sizeof (struct irem) /* remember data */
+ sf_malloc_prehunc
+ uSize /* size requested */
+ 4 /* overrun mark */
+ sf_malloc_endhunc
);
/* Check if there isn't anymore memory avaiable */
if (pTmp == NULL)
/* Check if there isn't anymore memory avaiable */
if (pTmp == NULL)
{
if (MyFlags & MY_FAE)
error_handler_hook=fatal_error_handler_hook;
if (MyFlags & (MY_FAE+MY_WME))
{
if (MyFlags & MY_FAE)
error_handler_hook=fatal_error_handler_hook;
if (MyFlags & (MY_FAE+MY_WME))
{
char buff[SC_MAXWIDTH];
my_errno=errno;
sprintf(buff,"Out of memory at line %d, '%s'", uLine, sFile);
my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
sprintf(buff,"needed %ld byte (%ldk), memory in use: %lu bytes (%ldk)",
(long) uSize, (long) ((uSize + 1023L) / 1024L),
(long) lMaxMemory, (long) (lMaxMemory + 1023L) / 1024L);
my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
}
DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'",
lMaxMemory,uLine, sFile));
if (MyFlags & MY_FAE)
exit(1);
DBUG_RETURN ((gptr) NULL);
char buff[SC_MAXWIDTH];
my_errno=errno;
sprintf(buff,"Out of memory at line %d, '%s'", uLine, sFile);
my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
sprintf(buff,"needed %ld byte (%ldk), memory in use: %lu bytes (%ldk)",
(long) uSize, (long) ((uSize + 1023L) / 1024L),
(long) lMaxMemory, (long) (lMaxMemory + 1023L) / 1024L);
my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG));
}
DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'",
lMaxMemory,uLine, sFile));
if (MyFlags & MY_FAE)
exit(1);
DBUG_RETURN ((gptr) NULL);
}
/* Fill up the structure */
*((long*) ((char*) &pTmp -> lSpecialValue+sf_malloc_prehunc)) = MAGICKEY;
pTmp -> aData[uSize + sf_malloc_prehunc+0] = MAGICEND0;
pTmp -> aData[uSize + sf_malloc_prehunc+1] = MAGICEND1;
pTmp -> aData[uSize + sf_malloc_prehunc+2] = MAGICEND2;
pTmp -> aData[uSize + sf_malloc_prehunc+3] = MAGICEND3;
pTmp -> sFileName = (my_string) sFile;
pTmp -> uLineNum = uLine;
pTmp -> uDataSize = uSize;
pTmp -> pPrev = NULL;
/* Fill up the structure */
*((long*) ((char*) &pTmp -> lSpecialValue+sf_malloc_prehunc)) = MAGICKEY;
pTmp -> aData[uSize + sf_malloc_prehunc+0] = MAGICEND0;
pTmp -> aData[uSize + sf_malloc_prehunc+1] = MAGICEND1;
pTmp -> aData[uSize + sf_malloc_prehunc+2] = MAGICEND2;
pTmp -> aData[uSize + sf_malloc_prehunc+3] = MAGICEND3;
pTmp -> sFileName = (my_string) sFile;
pTmp -> uLineNum = uLine;
pTmp -> uDataSize = uSize;
pTmp -> pPrev = NULL;
/* Add this remember structure to the linked list */
pthread_mutex_lock(&THR_LOCK_malloc);
if ((pTmp->pNext=pRememberRoot))
{
pRememberRoot -> pPrev = pTmp;
}
pRememberRoot = pTmp;
/* Add this remember structure to the linked list */
pthread_mutex_lock(&THR_LOCK_malloc);
if ((pTmp->pNext=pRememberRoot))
{
pRememberRoot -> pPrev = pTmp;
}
pRememberRoot = pTmp;
/* Keep the statistics */
lCurMemory += uSize;
if (lCurMemory > lMaxMemory) {
lMaxMemory = lCurMemory;
}
cNewCount++;
pthread_mutex_unlock(&THR_LOCK_malloc);
/* Keep the statistics */
lCurMemory += uSize;
if (lCurMemory > lMaxMemory) {
lMaxMemory = lCurMemory;
}
cNewCount++;
pthread_mutex_unlock(&THR_LOCK_malloc);
/* Set the memory to the aribtrary wierd value */
if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick)
bfill(&pTmp -> aData[sf_malloc_prehunc],uSize,
(char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL));
/* Return a pointer to the real data */
DBUG_PRINT("exit",("ptr: %lx",&(pTmp -> aData[sf_malloc_prehunc])));
if (sf_min_adress > (unsigned char *)&(pTmp -> aData[sf_malloc_prehunc]))
sf_min_adress = &(pTmp -> aData[sf_malloc_prehunc]);
if (sf_max_adress < (unsigned char *)&(pTmp -> aData[sf_malloc_prehunc]))
sf_max_adress = &(pTmp -> aData[sf_malloc_prehunc]);
DBUG_RETURN ((gptr) &(pTmp -> aData[sf_malloc_prehunc]));
/* Set the memory to the aribtrary wierd value */
if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick)
bfill(&pTmp -> aData[sf_malloc_prehunc],uSize,
(char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL));
/* Return a pointer to the real data */
DBUG_PRINT("exit",("ptr: %lx",&(pTmp -> aData[sf_malloc_prehunc])));
if (sf_min_adress > (unsigned char *)&(pTmp -> aData[sf_malloc_prehunc]))
sf_min_adress = &(pTmp -> aData[sf_malloc_prehunc]);
if (sf_max_adress < (unsigned char *)&(pTmp -> aData[sf_malloc_prehunc]))
sf_max_adress = &(pTmp -> aData[sf_malloc_prehunc]);
DBUG_RETURN ((gptr) &(pTmp -> aData[sf_malloc_prehunc]));
}
/*
@@ -212,7 +212,7 @@ gptr _mymalloc (size_t uSize, const char *sFile, uint uLine, myf MyFlags)
*/
gptr _myrealloc (register gptr pPtr, register size_t uSize,
const char *sFile, uint uLine, myf MyFlags)
const char *sFile, uint uLine, myf MyFlags)
{
struct remember *pRec;
gptr ptr;
@@ -228,14 +228,14 @@ gptr _myrealloc (register gptr pPtr, register size_t uSize,
DBUG_RETURN((gptr) NULL);
pRec = (struct remember *) ((char*) pPtr - sizeof (struct irem)-
sf_malloc_prehunc);
sf_malloc_prehunc);
if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc))
!= MAGICKEY)
{
fprintf (stderr, "Reallocating unallocated data at line %d, '%s'\n",
uLine, sFile);
uLine, sFile);
DBUG_PRINT("safe",("Reallocating unallocated data at line %d, '%s'",
uLine, sFile));
uLine, sFile));
(void) fflush(stderr);
DBUG_RETURN((gptr) NULL);
}
@@ -277,7 +277,7 @@ void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags)
/* Calculate the address of the remember structure */
pRec = (struct remember *) ((unsigned char*) pPtr-sizeof(struct irem)-
sf_malloc_prehunc);
sf_malloc_prehunc);
/* Check to make sure that we have a real remember structure */
/* Note: this test could fail for four reasons: */
@@ -290,7 +290,7 @@ void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags)
!= MAGICKEY)
{
fprintf (stderr, "Freeing unallocated data at line %d, '%s'\n",
uLine, sFile);
uLine, sFile);
DBUG_PRINT("safe",("Unallocated data at line %d, '%s'",uLine,sFile));
(void) fflush(stderr);
DBUG_VOID_RETURN;
@@ -323,15 +323,15 @@ void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags)
DBUG_VOID_RETURN;
}
/* Check if we have a wrong pointer */
/* Check if we have a wrong pointer */
static int check_ptr(const char *where, unsigned char *ptr, const char *sFile,
uint uLine)
uint uLine)
{
if (!ptr)
{
fprintf (stderr, "%s NULL pointer at line %d, '%s'\n",
where,uLine, sFile);
where,uLine, sFile);
DBUG_PRINT("safe",("Null pointer at line %d '%s'", uLine, sFile));
(void) fflush(stderr);
return 1;
@@ -340,9 +340,9 @@ static int check_ptr(const char *where, unsigned char *ptr, const char *sFile,
if ((long) ptr & (MY_ALIGN(1,sizeof(char *))-1))
{
fprintf (stderr, "%s wrong aligned pointer at line %d, '%s'\n",
where,uLine, sFile);
where,uLine, sFile);
DBUG_PRINT("safe",("Wrong aligned pointer at line %d, '%s'",
uLine,sFile));
uLine,sFile));
(void) fflush(stderr);
return 1;
}
@@ -350,9 +350,9 @@ static int check_ptr(const char *where, unsigned char *ptr, const char *sFile,
if (ptr < sf_min_adress || ptr > sf_max_adress)
{
fprintf (stderr, "%s pointer out of range at line %d, '%s'\n",
where,uLine, sFile);
where,uLine, sFile);
DBUG_PRINT("safe",("Pointer out of range at line %d '%s'",
uLine,sFile));
uLine,sFile));
(void) fflush(stderr);
return 1;
}
@@ -401,17 +401,16 @@ void TERMINATE (FILE *file)
{
if (file)
{
fprintf (file,
"\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'\n",
pPtr -> uDataSize,
(ulong) &(pPtr -> aData[sf_malloc_prehunc]),
pPtr -> uLineNum, pPtr -> sFileName);
(void) fflush(file);
fprintf (file,
"\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'\n",
pPtr -> uDataSize,
(ulong) &(pPtr -> aData[sf_malloc_prehunc]),
pPtr -> uLineNum, pPtr -> sFileName);
(void) fflush(file);
}
DBUG_PRINT("safe",
("%6u bytes at 0x%09lx, allocated at line %4d in '%s'",
pPtr -> uDataSize, &(pPtr -> aData[sf_malloc_prehunc]),
pPtr -> uLineNum, pPtr -> sFileName));
DBUG_PRINT("safe", ("%6u bytes at 0x%09lx, allocated at line %4u in '%s'",
pPtr -> uDataSize, (ulong) &(pPtr -> aData[sf_malloc_prehunc]),
pPtr -> uLineNum, pPtr->sFileName));
pPtr = pPtr -> pNext;
}
}
@@ -419,20 +418,20 @@ void TERMINATE (FILE *file)
if (file)
{
fprintf (file, "Maximum memory usage: %zu bytes (%ldk)\n",
lMaxMemory, (lMaxMemory + 1023L) / 1024L);
lMaxMemory, (lMaxMemory + 1023L) / 1024L);
(void) fflush(file);
}
DBUG_PRINT("safe",("Maximum memory usage: %ld bytes (%ldk)",
lMaxMemory, (lMaxMemory + 1023L) / 1024L));
lMaxMemory, (lMaxMemory + 1023L) / 1024L));
pthread_mutex_unlock(&THR_LOCK_malloc);
DBUG_VOID_RETURN;
}
/* Returns 0 if chunk is ok */
/* Returns 0 if chunk is ok */
static int _checkchunk (register struct remember *pRec, const char *sFile,
uint uLine)
uint uLine)
{
reg1 size_t uSize;
reg2 my_string magicp;
@@ -443,13 +442,13 @@ static int _checkchunk (register struct remember *pRec, const char *sFile,
!= MAGICKEY)
{
fprintf (stderr, "Memory allocated at %s:%d was underrun,",
pRec -> sFileName, pRec -> uLineNum);
pRec -> sFileName, pRec -> uLineNum);
fprintf (stderr, " discovered at %s:%d\n", sFile, uLine);
(void) fflush(stderr);
DBUG_PRINT("safe",("Underrun at %lx, allocated at %s:%d",
&(pRec -> aData[sf_malloc_prehunc]),
pRec -> sFileName,
pRec -> uLineNum));
&(pRec -> aData[sf_malloc_prehunc]),
pRec -> sFileName,
pRec -> uLineNum));
flag=1;
}
@@ -462,20 +461,20 @@ static int _checkchunk (register struct remember *pRec, const char *sFile,
*magicp++ != MAGICEND3)
{
fprintf (stderr, "Memory allocated at %s:%d was overrun,",
pRec -> sFileName, pRec -> uLineNum);
pRec -> sFileName, pRec -> uLineNum);
fprintf (stderr, " discovered at '%s:%d'\n", sFile, uLine);
(void) fflush(stderr);
DBUG_PRINT("safe",("Overrun at %lx, allocated at %s:%d",
&(pRec -> aData[sf_malloc_prehunc]),
pRec -> sFileName,
pRec -> uLineNum));
&(pRec -> aData[sf_malloc_prehunc]),
pRec -> sFileName,
pRec -> uLineNum));
flag=1;
}
return(flag);
}
/* Returns how many wrong chunks */
/* Returns how many wrong chunks */
int _sanity (const char *sFile, uint uLine)
{
@@ -500,10 +499,10 @@ int _sanity (const char *sFile, uint uLine)
} /* _sanity */
/* malloc and copy */
/* malloc and copy */
gptr _my_memdup(const unsigned char *from, size_t length, const char *sFile, uint uLine,
myf MyFlags)
myf MyFlags)
{
gptr ptr;
if ((ptr=_mymalloc(length,sFile,uLine,MyFlags)) != 0)
@@ -513,7 +512,7 @@ gptr _my_memdup(const unsigned char *from, size_t length, const char *sFile, uin
my_string _my_strdup(const char *from, const char *sFile, uint uLine,
myf MyFlags)
myf MyFlags)
{
gptr ptr;
size_t length= strlen(from)+1;

View File

@@ -228,6 +228,28 @@ size_t vio_read(Vio * vio, gptr buf, size_t size)
DBUG_RETURN(r);
}
/*
Return data from the beginning of the receive queue without removing
that data from the queue. A subsequent receive call will return the same data.
*/
my_bool vio_read_peek(Vio *vio, size_t *bytes)
{
#ifdef _WIN32
if (ioctlsocket(vio->sd, FIONREAD, bytes))
return TRUE;
#else
char buffer[1024];
ssize_t length;
vio_blocking(vio, 0);
length= recv(vio->sd, &buffer, sizeof(buffer), MSG_PEEK);
if (length < 0)
return TRUE;
*bytes= length;
#endif
return FALSE;
}
size_t vio_write(Vio * vio, const gptr buf, size_t size)
{

View File

@@ -80,7 +80,7 @@ static int use_utf8(MYSQL *my)
FAIL_IF(strcmp(row[0], "utf8"), "wrong character set");
}
FAIL_IF(mysql_errno(my), mysql_error(my));
mysql_free_result(res);
return OK;
}
@@ -573,7 +573,6 @@ struct my_tests_st my_tests[] = {
int main(int argc, char **argv)
{
if (argc > 1)
get_options(argc, argv);

View File

@@ -33,6 +33,7 @@ static int basic_connect(MYSQL *mysql)
mysql_free_result(res);
mysql_close(my);
return OK;
}
@@ -44,7 +45,7 @@ int thread_conc27(void);
DWORD WINAPI thread_conc27(void);
#endif
#define THREAD_NUM 100
#define THREAD_NUM 150
static int test_conc_27(MYSQL *mysql)
{
@@ -100,7 +101,7 @@ static int test_conc_27(MYSQL *mysql)
FAIL_IF(!row, "can't fetch row");
diag("row=%s", row[0]);
FAIL_IF(atoi(row[0]) != 100, "expected value 100");
FAIL_IF(atoi(row[0]) != THREAD_NUM, "expected value THREAD_NUM");
mysql_free_result(res);
return OK;
@@ -113,10 +114,13 @@ DWORD WINAPI thread_conc27(void)
#endif
{
MYSQL *mysql;
int rc;
int rc, i;
char *hname[]= {"localhost", "127.0.0.1", NULL};
mysql_thread_init();
mysql= mysql_init(NULL);
if(!mysql_real_connect(mysql, hostname, username, password, schema,
i= rand() % 3;
diag("Connecting to %s", hname[i]);
if(!mysql_real_connect(mysql, hname[i], username, password, schema,
port, socketname, 0))
{
diag("Error: %s", mysql_error(mysql));
@@ -128,8 +132,8 @@ DWORD WINAPI thread_conc27(void)
rc= mysql_query(mysql, "UPDATE t_conc27 SET a=a+1");
check_mysql_rc(rc, mysql);
pthread_mutex_unlock(&LOCK_test);
mysql_close(mysql);
mysql_thread_end();
mysql_close(mysql);
end:
mysql_thread_end();
return 0;
@@ -146,9 +150,6 @@ int main(int argc, char **argv)
{
mysql_library_init(0,0,NULL);
mysql_thread_init();
mysql_thread_end();
mysql_library_end();
if (argc > 1)
get_options(argc, argv);
@@ -157,5 +158,6 @@ int main(int argc, char **argv)
run_tests(my_tests);
mysql_server_end();
return(exit_status());
}