diff options
author | Sergei Golubchik <serg@mariadb.org> | 2018-02-01 21:55:30 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2018-02-02 10:09:44 +0100 |
commit | d4df7bc9b1fbdfb5c98134091a9ff998af60954f (patch) | |
tree | dfd2f5128ccf94b6e86d2475aee23acf53fa868c /mysys | |
parent | 80d3eee072025f34984e474ea160651eac9e11e5 (diff) | |
parent | 96cb428b350ba48ee17ad9968d08f5318e48258c (diff) | |
download | mariadb-git-d4df7bc9b1fbdfb5c98134091a9ff998af60954f.tar.gz |
Merge branch 'github/10.0' into 10.1
Diffstat (limited to 'mysys')
-rw-r--r-- | mysys/ma_dyncol.c | 60 | ||||
-rw-r--r-- | mysys/my_addr_resolve.c | 109 | ||||
-rw-r--r-- | mysys/my_alloc.c | 11 | ||||
-rw-r--r-- | mysys/my_default.c | 5 | ||||
-rw-r--r-- | mysys/my_lib.c | 10 | ||||
-rw-r--r-- | mysys/my_thr_init.c | 1 |
6 files changed, 133 insertions, 63 deletions
diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c index c46e9cd4456..1c5a4152292 100644 --- a/mysys/ma_dyncol.c +++ b/mysys/ma_dyncol.c @@ -3818,6 +3818,58 @@ end: DBUG_RETURN(rc); } +static +my_bool dynstr_append_json_quoted(DYNAMIC_STRING *str, + const char *append, size_t len) +{ + uint additional= ((str->alloc_increment && str->alloc_increment > 6) ? + str->alloc_increment : + 10); + uint lim= additional; + uint i; + if (dynstr_realloc(str, len + additional + 2)) + return TRUE; + str->str[str->length++]= '"'; + for (i= 0; i < len; i++) + { + register char c= append[i]; + if (unlikely(c <= 0x1F)) + { + if (lim < 5) + { + if (dynstr_realloc(str, additional)) + return TRUE; + lim+= additional; + } + lim-= 5; + str->str[str->length++]= '\\'; + str->str[str->length++]= 'u'; + str->str[str->length++]= '0'; + str->str[str->length++]= '0'; + str->str[str->length++]= (c < 0x10 ? '0' : '1'); + c%= 0x10; + str->str[str->length++]= (c < 0xA ? '0' + c : 'A' + (c - 0xA)); + } + else + { + if (c == '"' || c == '\\') + { + if (!lim) + { + if (dynstr_realloc(str, additional)) + return TRUE; + lim= additional; + } + lim--; + str->str[str->length++]= '\\'; + } + str->str[str->length++]= c; + } + } + str->str[str->length++]= '"'; + return FALSE; +} + enum enum_dyncol_func_result mariadb_dyncol_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, @@ -3883,7 +3935,10 @@ mariadb_dyncol_val_str(DYNAMIC_STRING *str, DYNAMIC_COLUMN_VALUE *val, return ER_DYNCOL_RESOURCE; } if (quote) - rc= dynstr_append_quoted(str, from, len, quote); + if (quote == DYNCOL_JSON_ESC) + rc= dynstr_append_json_quoted(str, from, len); + else + rc= dynstr_append_quoted(str, from, len, quote); else rc= dynstr_append_mem(str, from, len); if (alloc) @@ -4183,7 +4238,8 @@ mariadb_dyncol_json_internal(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json, } else { - if ((rc= mariadb_dyncol_val_str(json, &val, DYNCOL_UTF, '"')) < 0) + if ((rc= mariadb_dyncol_val_str(json, &val, DYNCOL_UTF, DYNCOL_JSON_ESC)) + < 0) goto err; } } diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c index 72b04119855..e9685985660 100644 --- a/mysys/my_addr_resolve.c +++ b/mysys/my_addr_resolve.c @@ -133,16 +133,52 @@ err: #include <m_string.h> #include <ctype.h> -#if defined(HAVE_LINK_H) && defined(HAVE_DLOPEN) -#include <link.h> -static ptrdiff_t offset= 0; -#else -#define offset 0 -#endif +#include <sys/wait.h> static int in[2], out[2]; -static int initialized= 0; +static pid_t pid; +static char addr2line_binary[1024]; static char output[1024]; + +int start_addr2line_fork(const char *binary_path) +{ + + if (pid > 0) + { + /* Don't leak FDs */ + close(in[1]); + close(out[0]); + /* Don't create zombie processes. */ + waitpid(pid, NULL, 0); + } + + if (pipe(in) < 0) + return 1; + if (pipe(out) < 0) + return 1; + + pid = fork(); + if (pid == -1) + return 1; + + if (!pid) /* child */ + { + dup2(in[0], 0); + dup2(out[1], 1); + close(in[0]); + close(in[1]); + close(out[0]); + close(out[1]); + execlp("addr2line", "addr2line", "-C", "-f", "-e", binary_path, NULL); + exit(1); + } + + close(in[0]); + close(out[1]); + + return 0; +} + int my_addr_resolve(void *ptr, my_addr_loc *loc) { char input[32]; @@ -158,13 +194,33 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc) int line_number_start = -1; ssize_t i; - FD_ZERO(&set); - FD_SET(out[0], &set); + Dl_info info; + void *offset; + + if (!dladdr(ptr, &info)) + return 1; + if (strcmp(addr2line_binary, info.dli_fname)) + { + /* We use dli_fname in case the path is longer than the length of our static + string. We don't want to allocate anything dynamicaly here as we are in + a "crashed" state. */ + if (start_addr2line_fork(info.dli_fname)) + { + addr2line_binary[0] = '\0'; + return 1; + } + /* Save result for future comparisons. */ + strnmov(addr2line_binary, info.dli_fname, sizeof(addr2line_binary)); + } + offset = info.dli_fbase; len= my_snprintf(input, sizeof(input), "%p\n", ptr - offset); if (write(in[1], input, len) <= 0) return 1; + FD_ZERO(&set); + FD_SET(out[0], &set); + /* 10 ms should be plenty of time for addr2line to issue a response. */ timeout.tv_sec = 0; timeout.tv_usec = 10000; @@ -221,41 +277,6 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc) const char *my_addr_resolve_init() { - if (!initialized) - { - pid_t pid; - -#if defined(HAVE_LINK_H) && defined(HAVE_DLOPEN) - struct link_map *lm = (struct link_map*) dlopen(0, RTLD_NOW); - if (lm) - offset= lm->l_addr; -#endif - - if (pipe(in) < 0) - return "pipe(in)"; - if (pipe(out) < 0) - return "pipe(out)"; - - pid = fork(); - if (pid == -1) - return "fork"; - - if (!pid) /* child */ - { - dup2(in[0], 0); - dup2(out[1], 1); - close(in[0]); - close(in[1]); - close(out[0]); - close(out[1]); - execlp("addr2line", "addr2line", "-C", "-f", "-e", my_progname, NULL); - exit(1); - } - - close(in[0]); - close(out[1]); - initialized= 1; - } return 0; } #endif diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index 7275f602525..1b0ef857afa 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -26,6 +26,8 @@ #define MALLOC_FLAG(A) ((A & 1) ? MY_THREAD_SPECIFIC : 0) +#define TRASH_MEM(X) TRASH_FREE(((char*)(X) + ((X)->size-(X)->left)), (X)->left) + /* Initialize memory root @@ -73,12 +75,13 @@ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, if (pre_alloc_size) { if ((mem_root->free= mem_root->pre_alloc= - (USED_MEM*) my_malloc(pre_alloc_size+ ALIGN_SIZE(sizeof(USED_MEM)), - MYF(my_flags)))) + (USED_MEM*) my_malloc(pre_alloc_size + ALIGN_SIZE(sizeof(USED_MEM)), + MYF(my_flags)))) { mem_root->free->size= pre_alloc_size+ALIGN_SIZE(sizeof(USED_MEM)); mem_root->free->left= pre_alloc_size; mem_root->free->next= 0; + TRASH_MEM(mem_root->free); } } #endif @@ -148,6 +151,7 @@ void reset_root_defaults(MEM_ROOT *mem_root, size_t block_size, mem->left= pre_alloc_size; mem->next= *prev; *prev= mem_root->pre_alloc= mem; + TRASH_MEM(mem); } else { @@ -248,6 +252,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) next->size= get_size; next->left= get_size-ALIGN_SIZE(sizeof(USED_MEM)); *prev=next; + TRASH_MEM(next); } point= (uchar*) ((char*) next+ (next->size-next->left)); @@ -316,8 +321,6 @@ void *multi_alloc_root(MEM_ROOT *root, ...) DBUG_RETURN((void*) start); } -#define TRASH_MEM(X) TRASH(((char*)(X) + ((X)->size-(X)->left)), (X)->left) - /* Mark all data in blocks free for reusage */ static inline void mark_blocks_free(MEM_ROOT* root) diff --git a/mysys/my_default.c b/mysys/my_default.c index dba22c4e58b..2358aed8f3b 100644 --- a/mysys/my_default.c +++ b/mysys/my_default.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2011, 2018, MariaDB Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -233,7 +234,7 @@ int my_search_option_files(const char *conf_file, int *argc, char ***argv, (char **) &my_defaults_group_suffix); if (! my_defaults_group_suffix) - my_defaults_group_suffix= getenv(STRINGIFY_ARG(DEFAULT_GROUP_SUFFIX_ENV)); + my_defaults_group_suffix= getenv("MYSQL_GROUP_SUFFIX"); if (forced_extra_defaults && !defaults_already_read) { diff --git a/mysys/my_lib.c b/mysys/my_lib.c index abc7b8a3161..8daed1101ec 100644 --- a/mysys/my_lib.c +++ b/mysys/my_lib.c @@ -119,10 +119,6 @@ MY_DIR *my_dir(const char *path, myf MyFlags) DBUG_ENTER("my_dir"); DBUG_PRINT("my",("path: '%s' MyFlags: %lu",path,MyFlags)); -#if !defined(HAVE_READDIR_R) - mysql_mutex_lock(&THR_LOCK_open); -#endif - tmp_file= directory_file_name(tmp_path, path); if (!(dirp= opendir(tmp_path))) @@ -174,9 +170,6 @@ MY_DIR *my_dir(const char *path, myf MyFlags) } (void) closedir(dirp); -#if !defined(HAVE_READDIR_R) - mysql_mutex_unlock(&THR_LOCK_open); -#endif if (MyFlags & MY_WANT_SORT) sort_dynamic(&dirh->array, (qsort_cmp) comp_names); @@ -187,9 +180,6 @@ MY_DIR *my_dir(const char *path, myf MyFlags) DBUG_RETURN(&dirh->dir); error: -#if !defined(HAVE_READDIR_R) - mysql_mutex_unlock(&THR_LOCK_open); -#endif my_errno=errno; if (dirp) (void) closedir(dirp); diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 1d3c3059bd5..f827fb136d3 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -385,7 +385,6 @@ void my_thread_end(void) /* Trash variable so that we can detect false accesses to my_thread_var */ tmp->init= 2; - TRASH(tmp, sizeof(*tmp)); free(tmp); } } |