23static const char *
const mysqlnd_debug_default_trace_file =
"/tmp/mysqlnd.trace";
24static const char *
const mysqlnd_debug_empty_string =
"";
31 if (!self->file_name) {
46 unsigned int line,
const char *
const file,
47 unsigned int level,
const char *
type,
const char * message)
49 char pipe_buffer[512];
53 unsigned int message_line_len;
54 unsigned int flags = self->flags;
55 char pid_buffer[10], time_buffer[30],
file_buffer[200],
56 line_buffer[6], level_buffer[7];
58 if (!self->stream &&
FAIL == self->m->open(self,
FALSE)) {
65 i =
MIN(level,
sizeof(pipe_buffer) / 2 - 1);
66 pipe_buffer[i*2] =
'\0';
68 pipe_buffer[i*2 - 1] =
' ';
69 pipe_buffer[i*2 - 2] =
'|';
74 snprintf(pid_buffer,
sizeof(pid_buffer) - 1,
"%5u: ", self->pid);
75 pid_buffer[
sizeof(pid_buffer) - 1 ] =
'\0';
82 const time_t sec =
tv.tv_sec;
83 if ((tm_p =
localtime((
const time_t *)&sec))) {
84 snprintf(time_buffer,
sizeof(time_buffer) - 1,
86 "%02d:%02d:%02d.%06d ",
88 tm_p->tm_hour, tm_p->tm_min, tm_p->tm_sec,
90 time_buffer[
sizeof(time_buffer) - 1 ] =
'\0';
92 time_buffer[0] =
'\0';
101 snprintf(line_buffer,
sizeof(line_buffer) - 1,
"%5u: ",
line);
102 line_buffer[
sizeof(line_buffer) - 1 ] =
'\0';
105 snprintf(level_buffer,
sizeof(level_buffer) - 1,
"%4u: ", level);
106 level_buffer[
sizeof(level_buffer) - 1 ] =
'\0';
109 message_line_len =
mnd_sprintf(&message_line, 0,
"%s%s%s%s%s%s%s%s\n",
115 pipe_buffer,
type?
type:
"", message);
120 self->m->close(self);
121 self->m->open(self,
TRUE);
131 unsigned int line,
const char *
const file,
132 unsigned int level,
const char *
type,
133 const char *format, ...)
135 char pipe_buffer[512];
138 char * message_line, *
buffer;
139 unsigned int message_line_len;
141 unsigned int flags = self->flags;
142 char pid_buffer[10], time_buffer[30],
file_buffer[200],
143 line_buffer[6], level_buffer[7];
145 if (!self->stream &&
FAIL == self->m->open(self,
FALSE)) {
152 i =
MIN(level,
sizeof(pipe_buffer) / 2 - 1);
153 pipe_buffer[i*2] =
'\0';
155 pipe_buffer[i*2 - 1] =
' ';
156 pipe_buffer[i*2 - 2] =
'|';
161 snprintf(pid_buffer,
sizeof(pid_buffer) - 1,
"%5u: ", self->pid);
162 pid_buffer[
sizeof(pid_buffer) - 1 ] =
'\0';
169 const time_t sec =
tv.tv_sec;
170 if ((tm_p =
localtime((
const time_t *)&sec))) {
171 snprintf(time_buffer,
sizeof(time_buffer) - 1,
173 "%02d:%02d:%02d.%06d ",
175 tm_p->tm_hour, tm_p->tm_min, tm_p->tm_sec,
177 time_buffer[
sizeof(time_buffer) - 1 ] =
'\0';
179 time_buffer[0] =
'\0';
188 snprintf(line_buffer,
sizeof(line_buffer) - 1,
"%5u: ",
line);
189 line_buffer[
sizeof(line_buffer) - 1 ] =
'\0';
192 snprintf(level_buffer,
sizeof(level_buffer) - 1,
"%4u: ", level);
193 level_buffer[
sizeof(level_buffer) - 1 ] =
'\0';
196 va_start(
args, format);
200 message_line_len =
mnd_sprintf(&message_line, 0,
"%s%s%s%s%s%s%s%s\n",
212 self->m->close(self);
213 self->m->open(self,
TRUE);
224 unsigned int line,
const char *
const file,
230 if ((uint32_t)
zend_stack_count(&self->call_stack) >= self->nest_level_limit) {
235 const char **
p = self->skip_functions;
239#ifndef MYSQLND_PROFILING_DISABLED
241 uint64_t some_time = 0;
252#ifndef MYSQLND_PROFILING_DISABLED
254 uint64_t some_time = 0;
259 if (zend_hash_num_elements(&self->not_filtered_functions) &&
270#ifndef MYSQLND_PROFILING_DISABLED
286#define PROFILE_UNDERPERFORM_THRESHOLD 10
294 uint64_t * parent_non_own_time_ptr =
NULL, * mine_non_own_time_ptr =
NULL;
295 uint64_t mine_non_own_time = 0;
301 if ((uint32_t)
zend_stack_count(&self->call_stack) >= self->nest_level_limit) {
307#ifndef MYSQLND_PROFILING_DISABLED
310 mine_non_own_time = *mine_non_own_time_ptr;
317 }
else if (!zend_hash_num_elements(&self->not_filtered_functions) ||
320#ifndef MYSQLND_PROFILING_DISABLED
321 if (
FALSE == profile_calls) {
325#ifndef MYSQLND_PROFILING_DISABLED
329 uint64_t own_time = call_time - mine_non_own_time;
333 *
func_name, (
unsigned int) call_time, (
unsigned int) own_time, (
unsigned int) mine_non_own_time
341 }
else if (mine_non_own_time > f_profile->
max_in_calls) {
346 if (own_time < f_profile->
min_own) {
348 }
else if (own_time > f_profile->
max_own) {
355 }
else if (call_time > f_profile->
max_total) {
365 if (f_profile->
avg_own < own_time) {
375 f_profile = &f_profile_stack;
379 f_profile->
calls = 1;
383 uint64_t parent_non_own_time = 0;
386 parent_non_own_time = *parent_non_own_time_ptr;
387 parent_non_own_time += call_time;
406#ifndef MYSQLND_PROFILING_DISABLED
411 self->m->log_va(self, __LINE__, __FILE__, 0,
"info : ",
412 "number of functions: %d", zend_hash_num_elements(&self->function_profiles));
414 self->m->log_va(self, __LINE__, __FILE__, -1,
"info : ",
415 "%-40s\tcalls=%5" PRIu64
416 " own_slow=%5" PRIu64
417 " in_calls_slow=%5" PRIu64
418 " total_slow=%5" PRIu64
422 " min_in_calls=%5" PRIu64
423 " max_in_calls=%7" PRIu64
424 " avg_in_calls=%7" PRIu64
425 " min_total=%5" PRIu64
426 " max_total=%7" PRIu64
427 " avg_total=%7" PRIu64
429 ,(uint64_t) f_profile->
calls
461 if (self->file_name && self->file_name != mysqlnd_debug_default_trace_file) {
462 efree(self->file_name);
463 self->file_name =
NULL;
492 self->nest_level_limit = 0;
493 if (self->file_name && self->file_name != mysqlnd_debug_default_trace_file) {
494 efree(self->file_name);
495 self->file_name =
NULL;
497 if (zend_hash_num_elements(&self->not_filtered_functions)) {
510 if (
mode[i] ==
'a' ||
mode[i] ==
'A') {
514 unsigned int j = i + 2;
521 if (
mode[
j] ==
':') {
531 if (!self->file_name)
532 self->file_name = (
char *) mysqlnd_debug_default_trace_file;
544 unsigned int j = i + 2;
547 if (
mode[
j] ==
':') {
565 if (
mode[
j] ==
':') {
574 "Expected list of functions for '%c' found none",
mode[i]);
586 if (
mode[i] ==
':') {
611 if (
mode[i+1] ==
',') {
612 unsigned int j = i + 2;
614 if (
mode[
j] ==
':') {
621 self->nest_level_limit = atoi(value_str);
626 self->nest_level_limit = 200;
655 if (
mode[i] ==
':') {
683static void free_ptr(
zval *
zv) {
693 ret->nest_level_limit = 0;
700 ret->m = & mysqlnd_mysqlnd_debug_methods;
701 ret->skip_functions = skip_functions;
715 if (trace_log_plugin) {
746 "Andrey Hristov <andrey@php.net>, Ulf Wendel <uw@php.net>, Georg Richter <georg@php.net>",
file(string $filename, int $flags=0, $context=null)
gettimeofday(bool $as_float=false)
log(float $num, float $base=M_E)
file_protected int file_buffer(struct magic_set *, php_stream *, zend_stat_t *, const char *, const void *, size_t)
PHPAPI ZEND_COLD void php_error_docref(const char *docref, int type, const char *format,...)
#define PHP_MYSQLND_VERSION
PHPAPI unsigned int mysqlnd_plugin_register_ex(struct st_mysqlnd_plugin_header *plugin)
#define MYSQLND_PLUGIN_API_VERSION
PHPAPI void * mysqlnd_plugin_find(const char *const name)
#define MYSQLND_VERSION_ID
#define MYSQLND_METHOD(class, method)
PHPAPI void mysqlnd_debug(const char *mode)
PHPAPI const char * mysqlnd_debug_std_no_trace_funcs[]
#define mnd_sprintf_free(p)
#define mnd_sprintf(p, mx_len, fmt,...)
#define mnd_vsprintf(p, mx_len, fmt, ap)
PHPAPI MYSQLND_DEBUG * mysqlnd_debug_init(const char *skip_functions[])
mysqlnd_debug_parser_state
PHPAPI void mysqlnd_debug(const char *mode)
#define PROFILE_UNDERPERFORM_THRESHOLD
void mysqlnd_debug_trace_plugin_register(void)
#define MYSQLND_DEBUG_DUMP_PID
#define MYSQLND_DEBUG_DUMP_LEVEL
#define MYSQLND_DEBUG_PROFILE_CALLS
#define MYSQLND_DEBUG_APPEND
#define MYSQLND_DEBUG_FLUSH
#define MYSQLND_DEBUG_DUMP_FILE
#define MYSQLND_DEBUG_TRACE_MEMORY_CALLS
#define MYSQLND_DEBUG_DUMP_TRACE
#define MYSQLND_DEBUG_DUMP_LINE
#define MYSQLND_DEBUG_DUMP_TIME
enum func_status enum_func_status
#define MYSQLND_CLASS_METHODS_END
struct st_mysqlnd_debug MYSQLND_DEBUG
#define MYSQLND_CLASS_METHODS_START(class)
localtime(?int $timestamp=null, bool $associative=false)
#define php_stream_close(stream)
#define php_stream_open_wrapper(path, mode, options, opened)
#define php_stream_write(stream, buf, count)
uint64_t total_underporm_calls
uint64_t in_calls_underporm_calls
uint64_t own_underporm_calls
struct st_mysqlnd_plugin_trace_log::@135250356370041002364233320207075236242207017335 methods
MYSQLND_DEBUG *(* trace_instance_init)(const char *skip_functions[])
#define estrndup(s, length)
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_str_add_empty_element(HashTable *ht, const char *str, size_t len)
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
#define ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(ht, _key, _ptr)
#define ZEND_HASH_FOREACH_END()
struct _zend_string zend_string
ZEND_API int zend_stack_push(zend_stack *stack, const void *element)
ZEND_API void * zend_stack_top(const zend_stack *stack)
ZEND_API int zend_stack_count(const zend_stack *stack)
ZEND_API void zend_stack_destroy(zend_stack *stack)
ZEND_API void zend_stack_init(zend_stack *stack, int size)
ZEND_API void zend_stack_del_top(zend_stack *stack)