File agent/ninedogs.c changed (mode: 100644) (index b3a0dd7..be9c85d) |
... |
... |
struct mem_node |
63 |
63 |
size_t size; |
size_t size; |
64 |
64 |
struct mem_node *next; |
struct mem_node *next; |
65 |
65 |
}; |
}; |
66 |
|
struct mem_node *mem_hash[64]; |
|
|
66 |
|
static __thread struct mem_node *mem_hash[64]; |
67 |
67 |
|
|
68 |
68 |
#define FD_NODE_DEV_NINEDOGS 1 |
#define FD_NODE_DEV_NINEDOGS 1 |
69 |
69 |
struct fd_node |
struct fd_node |
|
... |
... |
struct fd_node |
72 |
72 |
unsigned int flags; |
unsigned int flags; |
73 |
73 |
struct fd_node *next; |
struct fd_node *next; |
74 |
74 |
}; |
}; |
75 |
|
static __thread struct fd_node *fd_nodes[32]; |
|
|
75 |
|
static __thread struct fd_node *fd_nodes[32]; // TODO must be shared, but we need locking |
76 |
76 |
|
|
77 |
77 |
#define DLOPEN_MAX_ENTRIES 512 |
#define DLOPEN_MAX_ENTRIES 512 |
78 |
78 |
struct dlopen_node |
struct dlopen_node |
|
... |
... |
struct dlopen_node |
82 |
82 |
unsigned int count; |
unsigned int count; |
83 |
83 |
unsigned int pad; |
unsigned int pad; |
84 |
84 |
}; |
}; |
85 |
|
static struct dlopen_node dlopen_nodes[DLOPEN_MAX_ENTRIES]; |
|
|
85 |
|
static struct dlopen_node dlopen_nodes[DLOPEN_MAX_ENTRIES]; // TODO: we need locking |
86 |
86 |
|
|
87 |
87 |
// Custom allocator |
// Custom allocator |
88 |
|
static unsigned char my_malloc[200ULL * 65536ULL]; |
|
|
88 |
|
static unsigned char my_malloc[20ULL * 65536ULL]; |
89 |
89 |
static unsigned long my_malloc_pos; |
static unsigned long my_malloc_pos; |
90 |
90 |
|
|
91 |
91 |
static struct shared *shared; |
static struct shared *shared; |
|
... |
... |
static void my_trace_put_string_array(unsigned char *buf, unsigned int *i, char |
290 |
290 |
} |
} |
291 |
291 |
} |
} |
292 |
292 |
|
|
|
293 |
|
static void my_trace_put_hostent(unsigned char *buf, unsigned int *i, struct hostent *he) |
|
294 |
|
{ |
|
295 |
|
if (!he) |
|
296 |
|
return; |
|
297 |
|
|
|
298 |
|
int len = strlen(he->h_name); |
|
299 |
|
my_trace_put8(buf, i, len); |
|
300 |
|
my_trace_put(buf, i, he->h_name, len); |
|
301 |
|
|
|
302 |
|
for (int j = 0; ; j++) { |
|
303 |
|
if (!he->h_aliases[j]) { |
|
304 |
|
my_trace_put8(buf, i, 0); |
|
305 |
|
break; |
|
306 |
|
} |
|
307 |
|
|
|
308 |
|
len = strlen(he->h_aliases[j]); |
|
309 |
|
my_trace_put8(buf, i, len); |
|
310 |
|
my_trace_put(buf, i, he->h_aliases[j], len); |
|
311 |
|
} |
|
312 |
|
|
|
313 |
|
my_trace_put8(buf, i, he->h_addrtype); |
|
314 |
|
my_trace_put8(buf, i, he->h_length); |
|
315 |
|
|
|
316 |
|
int count = 0; |
|
317 |
|
for (int j = 0; ; j++) { |
|
318 |
|
if (!he->h_addr_list[j]) |
|
319 |
|
break; |
|
320 |
|
count++; |
|
321 |
|
} |
|
322 |
|
|
|
323 |
|
my_trace_put8(buf, i, count); |
|
324 |
|
for (int j = 0; j < count; j++) { |
|
325 |
|
xlog(0, " DEBUG: addr[%d]=[%s]\n", j, he->h_addr_list[j]); |
|
326 |
|
my_trace_put(buf, i, he->h_addr_list[j], he->h_length); |
|
327 |
|
} |
|
328 |
|
} |
|
329 |
|
|
293 |
330 |
/* |
/* |
294 |
|
* Returns how many byte were stored in |
|
|
331 |
|
* Returns how many byte were stored in |
295 |
332 |
*/ |
*/ |
296 |
333 |
static unsigned int my_trace_encode(unsigned char *buf, |
static unsigned int my_trace_encode(unsigned char *buf, |
297 |
334 |
const char *func, const char type, int save_errno, va_list va) |
const char *func, const char type, int save_errno, va_list va) |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
408 |
445 |
case 'd': |
case 'd': |
409 |
446 |
if (strcmp(func, "dlopen") == 0) { |
if (strcmp(func, "dlopen") == 0) { |
410 |
447 |
char *filename = va_arg(va, char *); |
char *filename = va_arg(va, char *); |
411 |
|
unsigned short len = strlen(filename); |
|
|
448 |
|
unsigned short len = filename ? strlen(filename) : 0; |
412 |
449 |
my_trace_put16(buf, &i, len); |
my_trace_put16(buf, &i, len); |
413 |
450 |
my_trace_put(buf, &i, filename, len); |
my_trace_put(buf, &i, filename, len); |
414 |
451 |
my_trace_put32(buf, &i, va_arg(va, int)); // flags |
my_trace_put32(buf, &i, va_arg(va, int)); // flags |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
465 |
502 |
if (ret == -1) |
if (ret == -1) |
466 |
503 |
my_trace_put32(buf, &i, save_errno); |
my_trace_put32(buf, &i, save_errno); |
467 |
504 |
} |
} |
|
505 |
|
} else if ((strcmp(func, "fsync") == 0) |
|
506 |
|
|| (strcmp(func, "fdatasync") == 0)) { |
|
507 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // fd |
|
508 |
|
if (type == 'r') { |
|
509 |
|
int ret = va_arg(va, int); |
|
510 |
|
my_trace_put32(buf, &i, ret); |
|
511 |
|
if (ret == -1) |
|
512 |
|
my_trace_put32(buf, &i, save_errno); |
|
513 |
|
} |
468 |
514 |
} break; |
} break; |
469 |
515 |
|
|
470 |
516 |
case 'g': |
case 'g': |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
486 |
532 |
int ret = va_arg(va, int); |
int ret = va_arg(va, int); |
487 |
533 |
my_trace_put32(buf, &i, ret); |
my_trace_put32(buf, &i, ret); |
488 |
534 |
} |
} |
489 |
|
} else if (strcmp(func, "gethostbyname") == 0) { |
|
|
535 |
|
} else if (strcmp(func, "gethostbyname") == 0) { // send hostent? |
490 |
536 |
char *name = va_arg(va, char *); |
char *name = va_arg(va, char *); |
491 |
537 |
uint16_t len = strlen(name); |
uint16_t len = strlen(name); |
492 |
538 |
my_trace_put16(buf, &i, len); |
my_trace_put16(buf, &i, len); |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
497 |
543 |
if (ret == -1) |
if (ret == -1) |
498 |
544 |
my_trace_put32(buf, &i, save_errno); |
my_trace_put32(buf, &i, save_errno); |
499 |
545 |
} |
} |
|
546 |
|
} else if (strcmp(func, "gethostbyname_r") == 0) { |
|
547 |
|
char *name = va_arg(va, char *); |
|
548 |
|
uint16_t len = strlen(name); |
|
549 |
|
my_trace_put16(buf, &i, len); |
|
550 |
|
my_trace_put(buf, &i, name, len); |
|
551 |
|
if (type == 'r') { |
|
552 |
|
int ret = va_arg(va, int); |
|
553 |
|
int my_h_errno = va_arg(va, int); |
|
554 |
|
struct hostent *he = va_arg(va, struct hostent *); |
|
555 |
|
my_trace_put32(buf, &i, ret); |
|
556 |
|
if (ret == -1) |
|
557 |
|
my_trace_put32(buf, &i, my_h_errno); |
|
558 |
|
else |
|
559 |
|
my_trace_put_hostent(buf, &i, he); |
|
560 |
|
} |
500 |
561 |
} else if (strcmp(func, "getrandom") == 0) { |
} else if (strcmp(func, "getrandom") == 0) { |
501 |
562 |
void *xbuf = NULL; |
void *xbuf = NULL; |
502 |
563 |
if (type == 'r') |
if (type == 'r') |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
542 |
603 |
} break; |
} break; |
543 |
604 |
|
|
544 |
605 |
case 'm': |
case 'm': |
545 |
|
if (strcmp(func, "mysqli_close") == 0) { |
|
|
606 |
|
if (strcmp(func, "mysqli_autocommit") == 0) { |
|
607 |
|
struct db_autocommit *a = va_arg(va, struct db_autocommit *); |
|
608 |
|
my_trace_put64(buf, &i, (uint64_t) a->link); |
|
609 |
|
my_trace_put_bool(buf, &i, a->value); |
|
610 |
|
if (type == 'r') |
|
611 |
|
my_trace_put_bool(buf, &i, a->ret); |
|
612 |
|
} else if (strcmp(func, "mysqli_close") == 0) { |
546 |
613 |
struct conn *c = va_arg(va, struct conn *); |
struct conn *c = va_arg(va, struct conn *); |
547 |
614 |
my_trace_put64(buf, &i, (uint64_t) c->dbh); |
my_trace_put64(buf, &i, (uint64_t) c->dbh); |
548 |
615 |
if (type == 'r') |
if (type == 'r') |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
553 |
620 |
my_trace_put(buf, &i, c->conn_str, c->conn_str_len); |
my_trace_put(buf, &i, c->conn_str, c->conn_str_len); |
554 |
621 |
if (type == 'r') |
if (type == 'r') |
555 |
622 |
my_trace_put64(buf, &i, (uint64_t) c->dbh); |
my_trace_put64(buf, &i, (uint64_t) c->dbh); |
556 |
|
} else if (strcmp(func, "mysqli_real_connect") == 0) { |
|
557 |
|
struct conn *c = va_arg(va, struct conn *); |
|
558 |
|
my_trace_put64(buf, &i, (uint64_t) c->dbh); |
|
559 |
|
my_trace_put32(buf, &i, c->conn_str_len); |
|
560 |
|
my_trace_put(buf, &i, c->conn_str, c->conn_str_len); |
|
561 |
|
my_trace_put32(buf, &i, c->flags); |
|
|
623 |
|
} else if (strcmp(func, "mysqli_fetch_all") == 0) { |
|
624 |
|
struct query *q = va_arg(va, struct query *); |
|
625 |
|
my_trace_put64(buf, &i, (uint64_t) q->res); |
|
626 |
|
my_trace_put32(buf, &i, q->mode); |
562 |
627 |
if (type == 'r') |
if (type == 'r') |
563 |
|
my_trace_put_bool(buf, &i, c->ret); |
|
564 |
|
/* TODO |
|
565 |
|
} else if (strcmp(func, "mysqli_prepare") == 0) { |
|
|
628 |
|
my_trace_put64(buf, &i, q->num); |
|
629 |
|
} else if (strcmp(func, "mysqli_fetch_array") == 0) { |
566 |
630 |
struct query *q = va_arg(va, struct query *); |
struct query *q = va_arg(va, struct query *); |
567 |
|
my_trace_put64(buf, &i, (uint64_t) q->dbh); |
|
568 |
|
my_trace_put16(buf, &i, q->q_len); |
|
569 |
|
my_trace_put(buf, &i, q->q, q->q_len); |
|
|
631 |
|
my_trace_put64(buf, &i, (uint64_t) q->res); |
|
632 |
|
my_trace_put32(buf, &i, q->mode); |
570 |
633 |
if (type == 'r') |
if (type == 'r') |
571 |
|
my_trace_put_bool(buf, &i, c->ret); |
|
572 |
|
*/ |
|
|
634 |
|
my_trace_put8(buf, &i, q->ret); |
|
635 |
|
} else if (strcmp(func, "mysqli_free_result") == 0) { |
|
636 |
|
struct free_result *fr = va_arg(va, struct free_result *); |
|
637 |
|
my_trace_put64(buf, &i, (uint64_t) fr->res); |
|
638 |
|
} else if (strcmp(func, "mysqli_prepare") == 0) { |
|
639 |
|
struct prepare *p = va_arg(va, struct prepare *); |
|
640 |
|
my_trace_put64(buf, &i, (uint64_t) p->dbh); |
|
641 |
|
my_trace_put16(buf, &i, p->q_len); |
|
642 |
|
my_trace_put(buf, &i, p->q, p->q_len); |
|
643 |
|
if (type == 'r') |
|
644 |
|
my_trace_put64(buf, &i, (uint64_t) p->stmt); |
573 |
645 |
} else if (strcmp(func, "mysqli_query") == 0) { |
} else if (strcmp(func, "mysqli_query") == 0) { |
574 |
646 |
struct query *q = va_arg(va, struct query *); |
struct query *q = va_arg(va, struct query *); |
575 |
647 |
my_trace_put64(buf, &i, (uint64_t) q->dbh); |
my_trace_put64(buf, &i, (uint64_t) q->dbh); |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
577 |
649 |
my_trace_put(buf, &i, q->q, q->q_len); |
my_trace_put(buf, &i, q->q, q->q_len); |
578 |
650 |
if (type == 'r') |
if (type == 'r') |
579 |
651 |
my_trace_put64(buf, &i, (uint64_t) q->res); |
my_trace_put64(buf, &i, (uint64_t) q->res); |
|
652 |
|
} else if (strcmp(func, "mysqli_real_connect") == 0) { |
|
653 |
|
struct conn *c = va_arg(va, struct conn *); |
|
654 |
|
my_trace_put64(buf, &i, (uint64_t) c->dbh); |
|
655 |
|
my_trace_put32(buf, &i, c->conn_str_len); |
|
656 |
|
my_trace_put(buf, &i, c->conn_str, c->conn_str_len); |
|
657 |
|
my_trace_put32(buf, &i, c->flags); |
|
658 |
|
if (type == 'r') |
|
659 |
|
my_trace_put_bool(buf, &i, c->ret); |
|
660 |
|
} else if (strcmp(func, "mysqli_stmt_execute") == 0) { |
|
661 |
|
struct execute *e = va_arg(va, struct execute *); |
|
662 |
|
my_trace_put64(buf, &i, (uint64_t) e->stmt); |
|
663 |
|
if (type == 'c') { |
|
664 |
|
my_trace_put16(buf, &i, e->params.len); |
|
665 |
|
for (unsigned short j = 0; j < e->params.len; j++) { |
|
666 |
|
struct params_array_one *pa = &e->params.list[j]; |
|
667 |
|
my_trace_put8(buf, &i, pa->type); |
|
668 |
|
if (pa->type == ND_PARAMS_TYPE_LONG) { |
|
669 |
|
my_trace_put64(buf, &i, pa->l); |
|
670 |
|
} else if (pa->type == ND_PARAMS_TYPE_DOUBLE) { |
|
671 |
|
my_trace_put_double(buf, &i, pa->d); |
|
672 |
|
} else if (pa->type == ND_PARAMS_TYPE_STRING) { |
|
673 |
|
my_trace_put16(buf, &i, pa->length); |
|
674 |
|
my_trace_put(buf, &i, pa->str, pa->length); |
|
675 |
|
} |
|
676 |
|
} |
|
677 |
|
} |
|
678 |
|
if (type == 'r') |
|
679 |
|
my_trace_put_bool(buf, &i, e->ret); |
|
680 |
|
} else if (strcmp(func, "mysqli_stmt_prepare") == 0) { |
|
681 |
|
struct prepare *p = va_arg(va, struct prepare *); |
|
682 |
|
my_trace_put64(buf, &i, (uint64_t) p->stmt); |
|
683 |
|
my_trace_put16(buf, &i, p->q_len); |
|
684 |
|
my_trace_put(buf, &i, p->q, p->q_len); |
|
685 |
|
if (type == 'r') |
|
686 |
|
my_trace_put_bool(buf, &i, p->ret); |
580 |
687 |
} break; |
} break; |
581 |
688 |
|
|
582 |
689 |
case 'n': |
case 'n': |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
637 |
744 |
if (ret == -1) |
if (ret == -1) |
638 |
745 |
my_trace_put32(buf, &i, save_errno); |
my_trace_put32(buf, &i, save_errno); |
639 |
746 |
} |
} |
|
747 |
|
} else if ((strcmp(func, "pread") == 0) |
|
748 |
|
|| (strcmp(func, "pread64") == 0)) { |
|
749 |
|
void *buf2 = NULL; |
|
750 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // fd |
|
751 |
|
if (type == 'r') |
|
752 |
|
buf2 = va_arg(va, void *); |
|
753 |
|
my_trace_put64(buf, &i, va_arg(va, size_t)); // count |
|
754 |
|
my_trace_put64(buf, &i, va_arg(va, off_t)); // offset |
|
755 |
|
if (type == 'r') { |
|
756 |
|
ssize_t ret = va_arg(va, ssize_t); |
|
757 |
|
my_trace_put64(buf, &i, ret); |
|
758 |
|
if (ret > 0) { |
|
759 |
|
unsigned short max = ret; |
|
760 |
|
if (max > 128) |
|
761 |
|
max = 128; |
|
762 |
|
my_trace_put16(buf, &i, max); |
|
763 |
|
my_trace_put(buf, &i, buf2, max); // data |
|
764 |
|
} else if (ret == -1) |
|
765 |
|
my_trace_put32(buf, &i, save_errno); |
|
766 |
|
} |
|
767 |
|
} else if (strcmp(func, "pthread_setname_np") == 0) { |
|
768 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, pthread_t)); |
|
769 |
|
char *name = va_arg(va, char *); |
|
770 |
|
unsigned short len = strlen(name); |
|
771 |
|
my_trace_put16(buf, &i, len); |
|
772 |
|
my_trace_put(buf, &i, name, len); |
|
773 |
|
int ret = va_arg(va, int); |
|
774 |
|
my_trace_put32(buf, &i, ret); |
|
775 |
|
if (ret == -1) |
|
776 |
|
my_trace_put32(buf, &i, save_errno); |
|
777 |
|
} else if (strcmp(func, "pthread_attr_setstacksize") == 0) { |
|
778 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // attr |
|
779 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, size_t)); // stack size |
|
780 |
|
int ret = va_arg(va, int); |
|
781 |
|
my_trace_put32(buf, &i, ret); |
|
782 |
|
if (ret == -1) |
|
783 |
|
my_trace_put32(buf, &i, save_errno); |
|
784 |
|
} else if (strcmp(func, "pthread_create") == 0) { |
|
785 |
|
my_trace_put32(buf, &i, (uint64_t) va_arg(va, uint32_t)); // thread |
|
786 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // attr TODO - how to encode it? |
|
787 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // arg |
|
788 |
|
int ret = va_arg(va, int); |
|
789 |
|
my_trace_put32(buf, &i, ret); |
|
790 |
|
if (ret == -1) |
|
791 |
|
my_trace_put32(buf, &i, save_errno); |
|
792 |
|
} else if ((strcmp(func, "pwrite") == 0) |
|
793 |
|
|| (strcmp(func, "pwrite64") == 0)) { |
|
794 |
|
void *buf2 = NULL; |
|
795 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // fd |
|
796 |
|
if (type == 'c') |
|
797 |
|
buf2 = va_arg(va, void *); |
|
798 |
|
size_t count = va_arg(va, size_t); |
|
799 |
|
my_trace_put64(buf, &i, count); |
|
800 |
|
my_trace_put64(buf, &i, va_arg(va, off_t)); // offset |
|
801 |
|
if (type == 'c') { |
|
802 |
|
unsigned short max = count; |
|
803 |
|
if (max > 128) max = 128; |
|
804 |
|
my_trace_put16(buf, &i, max); |
|
805 |
|
my_trace_put(buf, &i, buf2, max); // data |
|
806 |
|
} else { |
|
807 |
|
ssize_t ret = va_arg(va, ssize_t); |
|
808 |
|
my_trace_put64(buf, &i, ret); |
|
809 |
|
if (ret == -1) |
|
810 |
|
my_trace_put32(buf, &i, save_errno); |
|
811 |
|
} |
640 |
812 |
} else if (strcmp(func, "pg_close") == 0) { |
} else if (strcmp(func, "pg_close") == 0) { |
641 |
|
uint64_t h = va_arg(va, uint64_t); // handle |
|
642 |
|
my_trace_put64(buf, &i, h); |
|
|
813 |
|
struct conn *c = va_arg(va, struct conn *); |
|
814 |
|
my_trace_put64(buf, &i, (uint64_t) c->dbh); |
643 |
815 |
} else if ((strcmp(func, "pg_connect") == 0) |
} else if ((strcmp(func, "pg_connect") == 0) |
644 |
816 |
|| (strcmp(func, "pg_pconnect") == 0)) { |
|| (strcmp(func, "pg_pconnect") == 0)) { |
645 |
|
char *cs = va_arg(va, char *); |
|
646 |
|
unsigned int cs_len = va_arg(va, unsigned int); |
|
647 |
|
my_trace_put32(buf, &i, cs_len); |
|
648 |
|
my_trace_put(buf, &i, cs, cs_len); |
|
|
817 |
|
struct conn *c = va_arg(va, struct conn *); |
|
818 |
|
my_trace_put32(buf, &i, c->conn_str_len); |
|
819 |
|
my_trace_put(buf, &i, c->conn_str, c->conn_str_len); |
649 |
820 |
if (type == 'r') |
if (type == 'r') |
650 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // handle |
|
|
821 |
|
my_trace_put64(buf, &i, (uint64_t) c->dbh); |
651 |
822 |
} else if (strcmp(func, "pg_free_result") == 0) { |
} else if (strcmp(func, "pg_free_result") == 0) { |
652 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // res |
|
653 |
|
my_trace_put8(buf, &i, va_arg(va, int)); // ret |
|
|
823 |
|
struct free_result *fr = va_arg(va, struct free_result *); |
|
824 |
|
my_trace_put64(buf, &i, (uint64_t) fr->res); |
|
825 |
|
my_trace_put8(buf, &i, fr->ok); |
654 |
826 |
} else if ((strcmp(func, "pg_query") == 0) |
} else if ((strcmp(func, "pg_query") == 0) |
655 |
827 |
|| (strcmp(func, "pg_query_params") == 0) |
|| (strcmp(func, "pg_query_params") == 0) |
656 |
828 |
|| (strcmp(func, "pg_send_query") == 0) |
|| (strcmp(func, "pg_send_query") == 0) |
657 |
829 |
|| (strcmp(func, "pg_send_query_params") == 0)) { |
|| (strcmp(func, "pg_send_query_params") == 0)) { |
658 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // dbh |
|
659 |
|
char *q = va_arg(va, void *); |
|
660 |
|
unsigned short q_len = va_arg(va, unsigned int); |
|
661 |
|
my_trace_put16(buf, &i, q_len); |
|
662 |
|
my_trace_put(buf, &i, q, q_len); |
|
|
830 |
|
struct query *q = va_arg(va, struct query *); |
|
831 |
|
my_trace_put64(buf, &i, (uint64_t) q->dbh); |
|
832 |
|
my_trace_put16(buf, &i, q->q_len); |
|
833 |
|
my_trace_put(buf, &i, q->q, q->q_len); |
663 |
834 |
if (type == 'c') { |
if (type == 'c') { |
664 |
|
uint16_t params_len = va_arg(va, unsigned); |
|
665 |
|
my_trace_put16(buf, &i, params_len); |
|
666 |
|
uint16_t max = params_len; |
|
667 |
|
if (max > ND_PARAMS_MAX) max = ND_PARAMS_MAX; |
|
668 |
|
my_trace_put16(buf, &i, max); |
|
669 |
|
struct params_array *pa = va_arg(va, void *); |
|
670 |
|
for (unsigned short j = 0; j < max; j++) { |
|
|
835 |
|
my_trace_put16(buf, &i, q->params.len); |
|
836 |
|
for (unsigned short j = 0; j < q->params.len; j++) { |
|
837 |
|
struct params_array_one *pa = &q->params.list[j]; |
671 |
838 |
my_trace_put8(buf, &i, pa->type); |
my_trace_put8(buf, &i, pa->type); |
672 |
839 |
if (pa->type == ND_PARAMS_TYPE_LONG) { |
if (pa->type == ND_PARAMS_TYPE_LONG) { |
673 |
840 |
my_trace_put64(buf, &i, pa->l); |
my_trace_put64(buf, &i, pa->l); |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
677 |
844 |
my_trace_put16(buf, &i, pa->length); |
my_trace_put16(buf, &i, pa->length); |
678 |
845 |
my_trace_put(buf, &i, pa->str, pa->length); |
my_trace_put(buf, &i, pa->str, pa->length); |
679 |
846 |
} |
} |
680 |
|
pa++; |
|
681 |
847 |
} |
} |
682 |
848 |
} |
} |
683 |
849 |
if (type == 'r') { |
if (type == 'r') { |
684 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // res |
|
685 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, uint64_t)); // rows |
|
686 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, uint64_t)); // aff |
|
|
850 |
|
my_trace_put64(buf, &i, (uint64_t) q->res); |
|
851 |
|
my_trace_put64(buf, &i, q->num); |
|
852 |
|
my_trace_put64(buf, &i, q->aff); |
687 |
853 |
} |
} |
688 |
854 |
} else if (strcmp(func, "pg_get_result") == 0) { |
} else if (strcmp(func, "pg_get_result") == 0) { |
689 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // dbh |
|
690 |
|
(void) va_arg(va, void *); // ignore q |
|
691 |
|
(void) va_arg(va, unsigned int); // ignore q_len |
|
|
855 |
|
struct query *q = va_arg(va, struct query *); |
|
856 |
|
my_trace_put64(buf, &i, (uint64_t) q->dbh); |
692 |
857 |
if (type == 'r') { |
if (type == 'r') { |
693 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, void *)); // res |
|
694 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, uint64_t)); // rows |
|
695 |
|
my_trace_put64(buf, &i, (uint64_t) va_arg(va, uint64_t)); // aff |
|
|
858 |
|
my_trace_put64(buf, &i, (uint64_t) q->res); |
|
859 |
|
my_trace_put64(buf, &i, (uint64_t) q->num); |
|
860 |
|
my_trace_put64(buf, &i, (uint64_t) q->aff); |
696 |
861 |
} |
} |
697 |
862 |
} break; |
} break; |
698 |
863 |
|
|
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
811 |
976 |
my_trace_put32(buf, &i, ret); |
my_trace_put32(buf, &i, ret); |
812 |
977 |
if (ret == -1) |
if (ret == -1) |
813 |
978 |
my_trace_put32(buf, &i, save_errno); |
my_trace_put32(buf, &i, save_errno); |
|
979 |
|
} else if (strcmp(func, "sqlite3_bind_double") == 0) { |
|
980 |
|
my_trace_put64(buf, &i, va_arg(va, uint64_t)); // stmt |
|
981 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // index |
|
982 |
|
my_trace_put64(buf, &i, va_arg(va, double)); // value |
|
983 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // ret |
|
984 |
|
} else if (strcmp(func, "sqlite3_bind_int") == 0) { |
|
985 |
|
my_trace_put64(buf, &i, va_arg(va, uint64_t)); // stmt |
|
986 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // index |
|
987 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // value |
|
988 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // ret |
|
989 |
|
} else if (strcmp(func, "sqlite3_bind_int64") == 0) { |
|
990 |
|
my_trace_put64(buf, &i, va_arg(va, uint64_t)); // stmt |
|
991 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // index |
|
992 |
|
my_trace_put64(buf, &i, va_arg(va, int64_t)); // value |
|
993 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // ret |
|
994 |
|
} else if (strcmp(func, "sqlite3_bind_text") == 0) { |
|
995 |
|
my_trace_put64(buf, &i, va_arg(va, uint64_t)); // stmt |
|
996 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // index |
|
997 |
|
char *value = va_arg(va, char *); |
|
998 |
|
int max = va_arg(va, int); |
|
999 |
|
if (!value) |
|
1000 |
|
max = 0; |
|
1001 |
|
else if (max < 0) |
|
1002 |
|
max = strlen(value); |
|
1003 |
|
my_trace_put16(buf, &i, max); |
|
1004 |
|
my_trace_put(buf, &i, value, max); // value |
|
1005 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // ret |
|
1006 |
|
} else if (strcmp(func, "sqlite3_finalize") == 0) { |
|
1007 |
|
my_trace_put64(buf, &i, va_arg(va, uint64_t)); // stmt |
|
1008 |
|
my_trace_put32(buf, &i, va_arg(va, int)); // ret |
814 |
1009 |
} else if (strcmp(func, "sqlite3_open_v2") == 0) { |
} else if (strcmp(func, "sqlite3_open_v2") == 0) { |
815 |
1010 |
char *filename = va_arg(va, char *); |
char *filename = va_arg(va, char *); |
816 |
1011 |
uint16_t filename_len = strlen(filename); |
uint16_t filename_len = strlen(filename); |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
850 |
1045 |
my_trace_put32(buf, &i, va_arg(va, int)); // ret |
my_trace_put32(buf, &i, va_arg(va, int)); // ret |
851 |
1046 |
} else if (strcmp(func, "stat") == 0) { |
} else if (strcmp(func, "stat") == 0) { |
852 |
1047 |
char *pathname = va_arg(va, char *); |
char *pathname = va_arg(va, char *); |
853 |
|
unsigned short len = strlen(pathname); |
|
|
1048 |
|
unsigned short len = pathname ? strlen(pathname) : 0; |
854 |
1049 |
my_trace_put16(buf, &i, len); |
my_trace_put16(buf, &i, len); |
855 |
1050 |
my_trace_put(buf, &i, pathname, len); |
my_trace_put(buf, &i, pathname, len); |
856 |
|
struct stat *s = va_arg(va, void *); |
|
857 |
|
my_trace_put_stat(buf, &i, s); |
|
858 |
1051 |
if (type == 'r') { |
if (type == 'r') { |
|
1052 |
|
struct stat *s = va_arg(va, void *); |
|
1053 |
|
my_trace_put_stat(buf, &i, s); |
859 |
1054 |
int ret = va_arg(va, int); |
int ret = va_arg(va, int); |
860 |
1055 |
my_trace_put32(buf, &i, ret); |
my_trace_put32(buf, &i, ret); |
861 |
1056 |
if (ret == -1) |
if (ret == -1) |
|
... |
... |
static unsigned int my_trace_encode(unsigned char *buf, |
917 |
1112 |
|
|
918 |
1113 |
void my_trace(const char *func, const char type, ...) |
void my_trace(const char *func, const char type, ...) |
919 |
1114 |
{ |
{ |
|
1115 |
|
static __thread unsigned char out[64000]; // I had to reduce this for .NET! Stack too small! |
920 |
1116 |
int save_errno; |
int save_errno; |
921 |
1117 |
va_list va; |
va_list va; |
922 |
1118 |
int locked, r; |
int locked, r; |
|
... |
... |
void my_trace(const char *func, const char type, ...) |
935 |
1131 |
locked = 0; |
locked = 0; |
936 |
1132 |
do { |
do { |
937 |
1133 |
unsigned int ava, i; |
unsigned int ava, i; |
938 |
|
unsigned char out[1000000]; |
|
939 |
1134 |
|
|
940 |
1135 |
va_start(va, type); |
va_start(va, type); |
941 |
1136 |
i = my_trace_encode(out, func, type, save_errno, va); |
i = my_trace_encode(out, func, type, save_errno, va); |
|
... |
... |
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags) |
1920 |
2115 |
rest -= msg->msg_iov[i].iov_len; |
rest -= msg->msg_iov[i].iov_len; |
1921 |
2116 |
} |
} |
1922 |
2117 |
} |
} |
1923 |
|
|
|
1924 |
2118 |
my_trace(__func__, 'r', sockfd, msg, flags, ret); |
my_trace(__func__, 'r', sockfd, msg, flags, ret); |
1925 |
2119 |
|
|
1926 |
2120 |
return ret; |
return ret; |
|
... |
... |
struct hostent *gethostbyname(const char *name) |
2050 |
2244 |
return ret; |
return ret; |
2051 |
2245 |
} |
} |
2052 |
2246 |
|
|
|
2247 |
|
static int (*old_gethostbyname_r)(const char *name, struct hostent *restrict ret, |
|
2248 |
|
char *restrict buf, size_t buflen, |
|
2249 |
|
struct hostent **restrict result, |
|
2250 |
|
int *restrict h_errnop); |
|
2251 |
|
int gethostbyname_r(const char *name, struct hostent *restrict ret, |
|
2252 |
|
char *restrict buf, size_t buflen, |
|
2253 |
|
struct hostent **restrict result, |
|
2254 |
|
int *restrict h_errnop) |
|
2255 |
|
{ |
|
2256 |
|
int r; |
|
2257 |
|
|
|
2258 |
|
if (!old_gethostbyname_r) |
|
2259 |
|
old_gethostbyname_r = ninedogs_dlsym("gethostbyname_r"); |
|
2260 |
|
|
|
2261 |
|
xlog(100, "gethostbyname_r('%s', buflen=%zu)\n", name, buflen); |
|
2262 |
|
my_trace(__func__, 'c', name); |
|
2263 |
|
r = old_gethostbyname_r(name, ret, buf, buflen, result, h_errnop); |
|
2264 |
|
xlog(100, "gethostbyname_r('%s', buflen=%zu) = %d h_errno=%d *result=%p\n", |
|
2265 |
|
name, buflen, r, *h_errnop, result ? *result : NULL); |
|
2266 |
|
my_trace(__func__, 'r', name, r, *h_errnop, *result); |
|
2267 |
|
|
|
2268 |
|
return r; |
|
2269 |
|
} |
|
2270 |
|
|
2053 |
2271 |
int getaddrinfo(const char *restrict node, const char *restrict service, |
int getaddrinfo(const char *restrict node, const char *restrict service, |
2054 |
2272 |
const struct addrinfo *restrict hints, struct addrinfo **restrict res) |
const struct addrinfo *restrict hints, struct addrinfo **restrict res) |
2055 |
2273 |
{ |
{ |
|
... |
... |
int getaddrinfo(const char *restrict node, const char *restrict service, |
2065 |
2283 |
return ret; |
return ret; |
2066 |
2284 |
} |
} |
2067 |
2285 |
|
|
2068 |
|
// TODO: not yet in trace |
|
2069 |
2286 |
int pthread_create(pthread_t *restrict thread, |
int pthread_create(pthread_t *restrict thread, |
2070 |
2287 |
const pthread_attr_t *restrict attr, void *(*start_routine)(void *), |
const pthread_attr_t *restrict attr, void *(*start_routine)(void *), |
2071 |
2288 |
void *restrict arg) |
void *restrict arg) |
2072 |
2289 |
{ |
{ |
2073 |
2290 |
int ret; |
int ret; |
2074 |
2291 |
|
|
2075 |
|
//xlog(2, "pthread_create\n"); |
|
2076 |
|
|
|
|
2292 |
|
//xlog(2, "%s\n", __func__); |
2077 |
2293 |
ret = old_pthread_create(thread, attr, start_routine, arg); |
ret = old_pthread_create(thread, attr, start_routine, arg); |
2078 |
|
my_trace(__func__, 'R', thread, attr, arg, ret); |
|
|
2294 |
|
my_trace(__func__, 'R', ret == 0 ? *thread : 0, attr, arg, ret); |
2079 |
2295 |
|
|
2080 |
2296 |
return ret; |
return ret; |
2081 |
2297 |
} |
} |
2082 |
2298 |
|
|
|
2299 |
|
// TODO: trace |
2083 |
2300 |
int pthread_join(pthread_t thread, void **retval) |
int pthread_join(pthread_t thread, void **retval) |
2084 |
2301 |
{ |
{ |
2085 |
2302 |
int ret; |
int ret; |
2086 |
2303 |
|
|
2087 |
2304 |
//xlog(2, "pthread_join\n"); |
//xlog(2, "pthread_join\n"); |
2088 |
|
|
|
2089 |
2305 |
ret = old_pthread_join(thread, retval); |
ret = old_pthread_join(thread, retval); |
2090 |
|
my_trace(__func__, 'R', retval, ret); |
|
|
2306 |
|
my_trace(__func__, 'R', ret == 0 ? *retval : NULL, ret); |
2091 |
2307 |
|
|
2092 |
2308 |
return ret; |
return ret; |
2093 |
2309 |
} |
} |
2094 |
2310 |
|
|
2095 |
2311 |
#if 0 |
#if 0 |
2096 |
|
// this crashes! |
|
2097 |
2312 |
int pthread_attr_init(pthread_attr_t *attr) |
int pthread_attr_init(pthread_attr_t *attr) |
2098 |
2313 |
{ |
{ |
2099 |
2314 |
int ret; |
int ret; |
2100 |
2315 |
|
|
2101 |
|
xlog(2, "%s\n", __func__); |
|
|
2316 |
|
if (!old_pthread_attr_init) |
|
2317 |
|
old_pthread_attr_init = ninedogs_dlsym("pthread_attr_init"); |
2102 |
2318 |
|
|
|
2319 |
|
xlog(2, "%s\n", __func__); |
2103 |
2320 |
ret = old_pthread_attr_init(attr); |
ret = old_pthread_attr_init(attr); |
2104 |
2321 |
my_trace(__func__, 'R', attr, ret); |
my_trace(__func__, 'R', attr, ret); |
2105 |
2322 |
|
|
|
... |
... |
int pthread_attr_init(pthread_attr_t *attr) |
2110 |
2327 |
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) |
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) |
2111 |
2328 |
{ |
{ |
2112 |
2329 |
int ret; |
int ret; |
2113 |
|
//xlog(2, "pthread_attr_setstacksize(%zu)\n", stacksize); |
|
|
2330 |
|
|
|
2331 |
|
if (!old_pthread_attr_setstacksize) |
|
2332 |
|
old_pthread_attr_setstacksize = ninedogs_dlsym("pthread_attr_setstacksize"); |
|
2333 |
|
|
|
2334 |
|
xlog(2, "pthread_attr_setstacksize(%p, %zu)\n", attr, stacksize); |
2114 |
2335 |
|
|
2115 |
2336 |
ret = old_pthread_attr_setstacksize(attr, stacksize); |
ret = old_pthread_attr_setstacksize(attr, stacksize); |
2116 |
2337 |
my_trace(__func__, 'R', attr, stacksize, ret); |
my_trace(__func__, 'R', attr, stacksize, ret); |
|
... |
... |
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize) |
2118 |
2339 |
return ret; |
return ret; |
2119 |
2340 |
} |
} |
2120 |
2341 |
|
|
|
2342 |
|
static int (*old_pthread_setname_np)(pthread_t thread, const char *name); |
|
2343 |
|
int pthread_setname_np(pthread_t thread, const char *name) |
|
2344 |
|
{ |
|
2345 |
|
int ret; |
|
2346 |
|
|
|
2347 |
|
if (!old_pthread_setname_np) |
|
2348 |
|
old_pthread_setname_np = ninedogs_dlsym("pthread_setname_np"); |
|
2349 |
|
|
|
2350 |
|
xlog(2, "pthread_setname_np(%lu, %s)\n", thread, name); |
|
2351 |
|
ret = old_pthread_setname_np(thread, name); |
|
2352 |
|
my_trace(__func__, 'R', thread, name, ret); |
|
2353 |
|
|
|
2354 |
|
return ret; |
|
2355 |
|
} |
|
2356 |
|
|
2121 |
2357 |
// TODO: not yet in tracing (done on nd-trace) |
// TODO: not yet in tracing (done on nd-trace) |
2122 |
2358 |
int getsockopt(int sockfd, int level, int optname, void *restrict optval, |
int getsockopt(int sockfd, int level, int optname, void *restrict optval, |
2123 |
2359 |
socklen_t *restrict optlen) |
socklen_t *restrict optlen) |
|
... |
... |
void *dlopen(const char *filename, int flags) |
2317 |
2553 |
my_trace(__func__, 'c', filename, flags); |
my_trace(__func__, 'c', filename, flags); |
2318 |
2554 |
ret = old_dlopen(filename, flags); |
ret = old_dlopen(filename, flags); |
2319 |
2555 |
my_trace(__func__, 'r', filename, flags, ret); |
my_trace(__func__, 'r', filename, flags, ret); |
2320 |
|
xlog(100, "%s(%s, 0x%x) = %p\n", __func__, filename, flags, ret); |
|
2321 |
|
if (ret) { |
|
|
2556 |
|
if (filename && ret) { |
2322 |
2557 |
// TODO: should I add only 'flags=GLOBAL' entries? |
// TODO: should I add only 'flags=GLOBAL' entries? |
2323 |
2558 |
unsigned found = 0, first_free = DLOPEN_MAX_ENTRIES; |
unsigned found = 0, first_free = DLOPEN_MAX_ENTRIES; |
2324 |
2559 |
for (unsigned i = 0; i < DLOPEN_MAX_ENTRIES; i++) { |
for (unsigned i = 0; i < DLOPEN_MAX_ENTRIES; i++) { |
|
... |
... |
int listen(int sock, int backlog) |
2477 |
2712 |
void syslog(int priority, const char *format, ...) |
void syslog(int priority, const char *format, ...) |
2478 |
2713 |
{ |
{ |
2479 |
2714 |
va_list va; |
va_list va; |
2480 |
|
char buf[64000]; |
|
|
2715 |
|
char buf[4096]; |
2481 |
2716 |
|
|
2482 |
2717 |
if (!old_syslog) |
if (!old_syslog) |
2483 |
2718 |
ninedogs_init(); |
ninedogs_init(); |
|
... |
... |
int stat(const char *restrict pathname, struct stat *restrict statbuf) |
2534 |
2769 |
if (!old_stat) |
if (!old_stat) |
2535 |
2770 |
ninedogs_init(); |
ninedogs_init(); |
2536 |
2771 |
|
|
2537 |
|
xlog(100, "%s(%s, %p)\n", |
|
2538 |
|
__func__, pathname, statbuf); |
|
|
2772 |
|
xlog(100, "%s(%s, %p)\n", __func__, pathname, statbuf); |
2539 |
2773 |
|
|
2540 |
2774 |
my_trace(__func__, 'c', pathname); |
my_trace(__func__, 'c', pathname); |
2541 |
2775 |
ret = old_stat(pathname, statbuf); |
ret = old_stat(pathname, statbuf); |
|
... |
... |
int fork(void) |
2559 |
2793 |
return ret; |
return ret; |
2560 |
2794 |
} |
} |
2561 |
2795 |
|
|
|
2796 |
|
static int (*old_fsync)(int fd); |
|
2797 |
|
int fsync(int fd) |
|
2798 |
|
{ |
|
2799 |
|
int ret; |
|
2800 |
|
|
|
2801 |
|
if (!old_fsync) |
|
2802 |
|
old_fsync = ninedogs_dlsym("fsync"); |
|
2803 |
|
|
|
2804 |
|
xlog(100, "%s(%d)\n", __func__, fd); |
|
2805 |
|
my_trace(__func__, 'c', fd); |
|
2806 |
|
ret = old_fsync(fd); |
|
2807 |
|
my_trace(__func__, 'r', fd, ret); |
|
2808 |
|
|
|
2809 |
|
return ret; |
|
2810 |
|
} |
|
2811 |
|
|
|
2812 |
|
static int (*old_fdatasync)(int fd); |
|
2813 |
|
int fdatasync(int fd) |
|
2814 |
|
{ |
|
2815 |
|
int ret; |
|
2816 |
|
|
|
2817 |
|
if (!old_fdatasync) |
|
2818 |
|
old_fdatasync = ninedogs_dlsym("fdatasync"); |
|
2819 |
|
|
|
2820 |
|
xlog(100, "%s(%d)\n", __func__, fd); |
|
2821 |
|
my_trace(__func__, 'c', fd); |
|
2822 |
|
ret = old_fdatasync(fd); |
|
2823 |
|
my_trace(__func__, 'r', fd, ret); |
|
2824 |
|
|
|
2825 |
|
return ret; |
|
2826 |
|
} |
|
2827 |
|
|
|
2828 |
|
static ssize_t (*old_pread)(int fd, void *buf, size_t count, off_t offset); |
|
2829 |
|
ssize_t pread(int fd, void *buf, size_t count, off_t offset) |
|
2830 |
|
{ |
|
2831 |
|
ssize_t ret; |
|
2832 |
|
|
|
2833 |
|
if (!old_pread) |
|
2834 |
|
old_pread = ninedogs_dlsym("pread"); |
|
2835 |
|
|
|
2836 |
|
xlog(100, "%s(%d, %p, %zu, %zd)\n", __func__, fd, buf, count, offset); |
|
2837 |
|
my_trace(__func__, 'c', fd, count, offset); |
|
2838 |
|
ret = old_pread(fd, buf, count, offset); |
|
2839 |
|
my_trace(__func__, 'r', fd, buf, count, offset, ret); |
|
2840 |
|
|
|
2841 |
|
return ret; |
|
2842 |
|
} |
|
2843 |
|
|
|
2844 |
|
static ssize_t (*old_pread64)(int fd, void *buf, size_t count, off_t offset); |
|
2845 |
|
ssize_t pread64(int fd, void *buf, size_t count, off_t offset) |
|
2846 |
|
{ |
|
2847 |
|
ssize_t ret; |
|
2848 |
|
|
|
2849 |
|
if (!old_pread64) |
|
2850 |
|
old_pread64 = ninedogs_dlsym("pread64"); |
|
2851 |
|
|
|
2852 |
|
xlog(100, "%s(%d, %p, %zu, %zd)\n", __func__, fd, buf, count, offset); |
|
2853 |
|
my_trace(__func__, 'c', fd, count, offset); |
|
2854 |
|
ret = old_pread64(fd, buf, count, offset); |
|
2855 |
|
my_trace(__func__, 'r', fd, buf, count, offset, ret); |
|
2856 |
|
|
|
2857 |
|
return ret; |
|
2858 |
|
} |
|
2859 |
|
|
|
2860 |
|
static ssize_t (*old_pwrite)(int fd, const void *buf, size_t count, off_t offset); |
|
2861 |
|
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset) |
|
2862 |
|
{ |
|
2863 |
|
ssize_t ret; |
|
2864 |
|
|
|
2865 |
|
if (!old_pwrite) |
|
2866 |
|
old_pwrite = ninedogs_dlsym("pwrite"); |
|
2867 |
|
|
|
2868 |
|
xlog(100, "%s(%d, %p, %zu, %zd)\n", __func__, fd, buf, count, offset); |
|
2869 |
|
my_trace(__func__, 'c', fd, buf, count, offset); |
|
2870 |
|
ret = old_pwrite(fd, buf, count, offset); |
|
2871 |
|
my_trace(__func__, 'r', fd, count, offset, ret); |
|
2872 |
|
|
|
2873 |
|
return ret; |
|
2874 |
|
} |
|
2875 |
|
|
|
2876 |
|
static ssize_t (*old_pwrite64)(int fd, const void *buf, size_t count, off_t offset); |
|
2877 |
|
ssize_t pwrite64(int fd, const void *buf, size_t count, off_t offset) |
|
2878 |
|
{ |
|
2879 |
|
ssize_t ret; |
|
2880 |
|
|
|
2881 |
|
if (!old_pwrite64) |
|
2882 |
|
old_pwrite64 = ninedogs_dlsym("pwrite64"); |
|
2883 |
|
|
|
2884 |
|
xlog(100, "%s(%d, %p, %zu, %zd)\n", __func__, fd, buf, count, offset); |
|
2885 |
|
my_trace(__func__, 'c', fd, buf, count, offset); |
|
2886 |
|
ret = old_pwrite64(fd, buf, count, offset); |
|
2887 |
|
my_trace(__func__, 'r', fd, count, offset, ret); |
|
2888 |
|
|
|
2889 |
|
return ret; |
|
2890 |
|
} |
|
2891 |
|
|
2562 |
2892 |
static int (*old_sqlite3_open)(const char *, void **); |
static int (*old_sqlite3_open)(const char *, void **); |
2563 |
2893 |
int sqlite3_open(const char *filename, void **ppdb) |
int sqlite3_open(const char *filename, void **ppdb) |
2564 |
2894 |
{ |
{ |
|
... |
... |
int sqlite3_prepare_v2(void *h, const char *sql, int nByte, void **stmt, const c |
2650 |
2980 |
return ret; |
return ret; |
2651 |
2981 |
} |
} |
2652 |
2982 |
|
|
|
2983 |
|
static int (*old_sqlite3_finalize)(void *); |
|
2984 |
|
int sqlite3_finalize(void *pstmt) |
|
2985 |
|
{ |
|
2986 |
|
int ret; |
|
2987 |
|
|
|
2988 |
|
if (!old_sqlite3_finalize) |
|
2989 |
|
old_sqlite3_finalize = ninedogs_dlsym("sqlite3_finalize"); |
|
2990 |
|
|
|
2991 |
|
ret = old_sqlite3_finalize(pstmt); |
|
2992 |
|
xlog(100, "%s(pstmt=%p) = %d\n", __func__, pstmt); |
|
2993 |
|
my_trace(__func__, 'R', pstmt, ret); |
|
2994 |
|
|
|
2995 |
|
return ret; |
|
2996 |
|
} |
|
2997 |
|
|
2653 |
2998 |
static int (*old_sqlite3_step)(void *); |
static int (*old_sqlite3_step)(void *); |
2654 |
2999 |
int sqlite3_step(void *stmt) |
int sqlite3_step(void *stmt) |
2655 |
3000 |
{ |
{ |
|
... |
... |
int sqlite3_step(void *stmt) |
2666 |
3011 |
return ret; |
return ret; |
2667 |
3012 |
} |
} |
2668 |
3013 |
|
|
|
3014 |
|
static int (*old_sqlite3_bind_double)(void *, int, double); |
|
3015 |
|
int sqlite3_bind_double(void *stmt, int index, double value) |
|
3016 |
|
{ |
|
3017 |
|
int ret; |
|
3018 |
|
|
|
3019 |
|
if (!old_sqlite3_bind_double) |
|
3020 |
|
old_sqlite3_bind_double = ninedogs_dlsym("sqlite3_bind_double"); |
|
3021 |
|
|
|
3022 |
|
ret = old_sqlite3_bind_double(stmt, index, value); |
|
3023 |
|
xlog(100, "%s(stmt=%p, %d, %f) = %d\n", __func__, stmt, index, value, ret); |
|
3024 |
|
my_trace(__func__, 'R', stmt, index, value, ret); |
|
3025 |
|
|
|
3026 |
|
return ret; |
|
3027 |
|
} |
|
3028 |
|
|
|
3029 |
|
static int (*old_sqlite3_bind_int)(void *, int, int); |
|
3030 |
|
int sqlite3_bind_int(void *stmt, int index, int value) |
|
3031 |
|
{ |
|
3032 |
|
int ret; |
|
3033 |
|
|
|
3034 |
|
if (!old_sqlite3_bind_int) |
|
3035 |
|
old_sqlite3_bind_int = ninedogs_dlsym("sqlite3_bind_int"); |
|
3036 |
|
|
|
3037 |
|
ret = old_sqlite3_bind_int(stmt, index, value); |
|
3038 |
|
xlog(100, "%s(stmt=%p, %d, %d) = %d\n", __func__, stmt, index, value, ret); |
|
3039 |
|
my_trace(__func__, 'R', stmt, index, value, ret); |
|
3040 |
|
|
|
3041 |
|
return ret; |
|
3042 |
|
} |
|
3043 |
|
|
|
3044 |
|
static int (*old_sqlite3_bind_int64)(void *, int, uint64_t); |
|
3045 |
|
int sqlite3_bind_int64(void *stmt, int index, uint64_t value) |
|
3046 |
|
{ |
|
3047 |
|
int ret; |
|
3048 |
|
|
|
3049 |
|
if (!old_sqlite3_bind_int64) |
|
3050 |
|
old_sqlite3_bind_int64 = ninedogs_dlsym("sqlite3_bind_int64"); |
|
3051 |
|
|
|
3052 |
|
ret = old_sqlite3_bind_int64(stmt, index, value); |
|
3053 |
|
xlog(100, "%s(stmt=%p, %d, %ld) = %d\n", __func__, stmt, index, value, ret); |
|
3054 |
|
my_trace(__func__, 'R', stmt, index, value, ret); |
|
3055 |
|
|
|
3056 |
|
return ret; |
|
3057 |
|
} |
|
3058 |
|
|
|
3059 |
|
static int (*old_sqlite3_bind_text)(void *, int, const char *, int, void *); |
|
3060 |
|
int sqlite3_bind_text(void *stmt, int index, const char *value, int len, void *func) |
|
3061 |
|
{ |
|
3062 |
|
int ret; |
|
3063 |
|
|
|
3064 |
|
if (!old_sqlite3_bind_text) |
|
3065 |
|
old_sqlite3_bind_text = ninedogs_dlsym("sqlite3_bind_text"); |
|
3066 |
|
|
|
3067 |
|
ret = old_sqlite3_bind_text(stmt, index, value, len, func); |
|
3068 |
|
xlog(100, "%s(stmt=%p, %d, '%s', len=%d) = %d\n", __func__, stmt, index, value, len, ret); |
|
3069 |
|
my_trace(__func__, 'R', stmt, index, value, len, ret); |
|
3070 |
|
|
|
3071 |
|
return ret; |
|
3072 |
|
} |
|
3073 |
|
|
File agent/php.c changed (mode: 100644) (index 94e2548..547b340) |
... |
... |
static void php_zed_dump(const char *prefix, struct zend_execute_data *p) |
319 |
319 |
} |
} |
320 |
320 |
} |
} |
321 |
321 |
|
|
322 |
|
static void zend_array_to_params_array(struct query *q, struct zend_array *za) |
|
|
322 |
|
static void zend_array_to_params_array(struct params_array *p, struct zend_array *za) |
323 |
323 |
{ |
{ |
324 |
|
unsigned int i = 0, max; |
|
|
324 |
|
unsigned int i = 0; |
325 |
325 |
|
|
326 |
326 |
xlog(100, " nTableMask=0x%x nNumUsed=%u nNumOfElements=%u nTableSize=%u" |
xlog(100, " nTableMask=0x%x nNumUsed=%u nNumOfElements=%u nTableSize=%u" |
327 |
327 |
" nInternalPointer=%u flags=0x%x[%s]\n", |
" nInternalPointer=%u flags=0x%x[%s]\n", |
328 |
328 |
za->nTableMask, za->nNumUsed, za->nNumOfElements, za->nTableSize, |
za->nTableMask, za->nNumUsed, za->nNumOfElements, za->nTableSize, |
329 |
329 |
za->nInternalPointer, za->u.flags, za->u.flags & 4 ? "packed" : ""); |
za->nInternalPointer, za->u.flags, za->u.flags & 4 ? "packed" : ""); |
330 |
330 |
|
|
331 |
|
max = za->nNumUsed; |
|
332 |
|
if (max > ND_PARAMS_MAX) |
|
333 |
|
max = ND_PARAMS_MAX; |
|
|
331 |
|
p->len = za->nNumUsed; |
|
332 |
|
if (p->len > ND_PARAMS_MAX) |
|
333 |
|
p->len = ND_PARAMS_MAX; |
334 |
334 |
|
|
335 |
335 |
struct Bucket *bs = za->arData, *be = za->arData + za->nNumUsed; |
struct Bucket *bs = za->arData, *be = za->arData + za->nNumUsed; |
336 |
336 |
for (; bs != be; bs++) { |
for (; bs != be; bs++) { |
|
... |
... |
static void zend_array_to_params_array(struct query *q, struct zend_array *za) |
354 |
354 |
bs, bs->h, zs, php_get_type(_z), php_get_value(_z)); |
bs, bs->h, zs, php_get_type(_z), php_get_value(_z)); |
355 |
355 |
|
|
356 |
356 |
if (_z->u1.v.type == 4) { |
if (_z->u1.v.type == 4) { |
357 |
|
q->params[i].type = ND_PARAMS_TYPE_LONG; |
|
358 |
|
q->params[i].l = _z->value.lval; |
|
|
357 |
|
p->list[i].type = ND_PARAMS_TYPE_LONG; |
|
358 |
|
p->list[i].l = _z->value.lval; |
359 |
359 |
} else if (_z->u1.v.type == 5) { |
} else if (_z->u1.v.type == 5) { |
360 |
|
q->params[i].type = ND_PARAMS_TYPE_DOUBLE; |
|
361 |
|
q->params[i].d = _z->value.dval; |
|
|
360 |
|
p->list[i].type = ND_PARAMS_TYPE_DOUBLE; |
|
361 |
|
p->list[i].d = _z->value.dval; |
362 |
362 |
} else if (_z->u1.v.type == 6) { |
} else if (_z->u1.v.type == 6) { |
363 |
|
q->params[i].type = ND_PARAMS_TYPE_STRING; |
|
|
363 |
|
p->list[i].type = ND_PARAMS_TYPE_STRING; |
364 |
364 |
struct zend_string *zs = _z->value.str; |
struct zend_string *zs = _z->value.str; |
365 |
|
q->params[i].str = zs->val; |
|
366 |
|
q->params[i].length = zs->len; |
|
|
365 |
|
p->list[i].str = zs->val; |
|
366 |
|
p->list[i].length = zs->len; |
367 |
367 |
} |
} |
368 |
368 |
|
|
369 |
369 |
i++; |
i++; |
370 |
|
if (i == max) |
|
|
370 |
|
if (i == p->len) |
371 |
371 |
break; |
break; |
372 |
372 |
} |
} |
373 |
|
|
|
374 |
|
q->params_len = za->nNumUsed; |
|
375 |
373 |
} |
} |
376 |
374 |
|
|
377 |
375 |
void *(*old_pg_last_error)(struct zend_execute_data *, struct zval *); |
void *(*old_pg_last_error)(struct zend_execute_data *, struct zval *); |
|
... |
... |
static void *my_pg_free_result(struct zend_execute_data *e, struct zval *retv) |
510 |
508 |
{ |
{ |
511 |
509 |
void *ret; |
void *ret; |
512 |
510 |
unsigned int s; |
unsigned int s; |
|
511 |
|
struct zval *z; |
513 |
512 |
struct free_result fr; |
struct free_result fr; |
514 |
513 |
|
|
515 |
514 |
unsigned int num_args = e->This.u2.num_args; |
unsigned int num_args = e->This.u2.num_args; |
|
... |
... |
static void *my_pg_free_result(struct zend_execute_data *e, struct zval *retv) |
518 |
517 |
//php_zval_dump(" retv: ", retv); |
//php_zval_dump(" retv: ", retv); |
519 |
518 |
|
|
520 |
519 |
s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
521 |
|
struct zval *z = (struct zval *) e + s; |
|
522 |
|
|
|
523 |
520 |
fr.type = 'P'; |
fr.type = 'P'; |
|
521 |
|
|
|
522 |
|
// res |
|
523 |
|
z = (struct zval *) e + s; s++; |
524 |
524 |
fr.res = z->value.p; |
fr.res = z->value.p; |
525 |
525 |
|
|
526 |
|
ret = old_pg_free_result(e, retv); // ret will be NULL! |
|
|
526 |
|
ret = old_pg_free_result(e, retv); |
527 |
527 |
// 'ret' is null here |
// 'ret' is null here |
528 |
528 |
|
|
529 |
529 |
if (retv->u1.v.type == 3) { // true |
if (retv->u1.v.type == 3) { // true |
|
... |
... |
static void *my_pg_query(struct zend_execute_data *e, struct zval *retv) |
632 |
632 |
s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
633 |
633 |
para = (struct zval *) e + s; |
para = (struct zval *) e + s; |
634 |
634 |
qs.type = 'P'; // if dbh is null, we do not know the type |
qs.type = 'P'; // if dbh is null, we do not know the type |
635 |
|
qs.params_len = 0; |
|
|
635 |
|
qs.params.len = 0; |
636 |
636 |
|
|
637 |
637 |
if (num_args == 2) { |
if (num_args == 2) { |
638 |
638 |
// link |
// link |
|
... |
... |
static void *my_pg_send_query(struct zend_execute_data *e, struct zval *retv) |
692 |
692 |
|
|
693 |
693 |
s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
694 |
694 |
qs.type = 'P'; |
qs.type = 'P'; |
695 |
|
qs.params_len = 0; |
|
|
695 |
|
qs.params.len = 0; |
696 |
696 |
|
|
697 |
697 |
// link |
// link |
698 |
698 |
z = (struct zval *) e + s; s++; |
z = (struct zval *) e + s; s++; |
|
... |
... |
static void *my_pg_get_result(struct zend_execute_data *e, struct zval *retv) |
744 |
744 |
para = (struct zval *) e + s; |
para = (struct zval *) e + s; |
745 |
745 |
qs.type = 'P'; |
qs.type = 'P'; |
746 |
746 |
qs.q = NULL; |
qs.q = NULL; |
747 |
|
qs.params_len = 0; |
|
|
747 |
|
qs.params.len = 0; |
748 |
748 |
|
|
749 |
749 |
// link |
// link |
750 |
750 |
z = (struct zval *) e + s; s++; |
z = (struct zval *) e + s; s++; |
|
... |
... |
static void *my_pg_query_params(struct zend_execute_data *e, struct zval *retv) |
818 |
818 |
// params (array) |
// params (array) |
819 |
819 |
z = (struct zval *) e + s; s++; |
z = (struct zval *) e + s; s++; |
820 |
820 |
struct zend_array *za = z->value.arr; |
struct zend_array *za = z->value.arr; |
821 |
|
zend_array_to_params_array(&qs, za); |
|
|
821 |
|
zend_array_to_params_array(&qs.params, za); |
822 |
822 |
|
|
823 |
823 |
ninedogs_process_db("pg_query_params", NINEDOGS_DB_QUERY_START, &qs); |
ninedogs_process_db("pg_query_params", NINEDOGS_DB_QUERY_START, &qs); |
824 |
824 |
ret = old_pg_query_params(e, retv); |
ret = old_pg_query_params(e, retv); |
|
... |
... |
static void *my_pg_send_query_params(struct zend_execute_data *e, struct zval *r |
880 |
880 |
// params (array) |
// params (array) |
881 |
881 |
z = (struct zval *) e + s; s++; |
z = (struct zval *) e + s; s++; |
882 |
882 |
struct zend_array *za = z->value.arr; |
struct zend_array *za = z->value.arr; |
883 |
|
zend_array_to_params_array(&qs, za); |
|
|
883 |
|
zend_array_to_params_array(&qs.params, za); |
884 |
884 |
|
|
885 |
885 |
ninedogs_process_db("pg_send_query_params", NINEDOGS_DB_QUERY_START, &qs); |
ninedogs_process_db("pg_send_query_params", NINEDOGS_DB_QUERY_START, &qs); |
886 |
886 |
ret = old_pg_send_query_params(e, retv); |
ret = old_pg_send_query_params(e, retv); |
|
... |
... |
static void *my_mysqli_connect(struct zend_execute_data *e, struct zval *retv) |
921 |
921 |
|
|
922 |
922 |
if (num_args >= 1) { // host |
if (num_args >= 1) { // host |
923 |
923 |
z = (struct zval *) e + s; s++; |
z = (struct zval *) e + s; s++; |
924 |
|
php_zval_dump(" host: ", z); |
|
|
924 |
|
//php_zval_dump(" host: ", z); |
925 |
925 |
if (z->u1.v.type == 6) // string |
if (z->u1.v.type == 6) // string |
926 |
926 |
host = z->value.str->val; |
host = z->value.str->val; |
927 |
927 |
} |
} |
|
... |
... |
static void *my_mysqli_real_connect(struct zend_execute_data *e, struct zval *re |
1004 |
1004 |
|
|
1005 |
1005 |
if (num_args >= 2) { // host |
if (num_args >= 2) { // host |
1006 |
1006 |
z = (struct zval *) e + s; s++; |
z = (struct zval *) e + s; s++; |
1007 |
|
php_zval_dump(" host: ", z); |
|
|
1007 |
|
//php_zval_dump(" host: ", z); |
1008 |
1008 |
if (z->u1.v.type == 6) // string |
if (z->u1.v.type == 6) // string |
1009 |
1009 |
host = z->value.str->val; |
host = z->value.str->val; |
1010 |
1010 |
} |
} |
|
... |
... |
static void *my_mysqli_query(struct zend_execute_data *e, struct zval *retv) |
1085 |
1085 |
s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
1086 |
1086 |
para = (struct zval *) e + s; |
para = (struct zval *) e + s; |
1087 |
1087 |
qs.type = 'M'; |
qs.type = 'M'; |
1088 |
|
qs.params_len = 0; |
|
|
1088 |
|
qs.params.len = 0; |
1089 |
1089 |
|
|
1090 |
1090 |
// link |
// link |
1091 |
1091 |
z = (struct zval *) e + s; s++; |
z = (struct zval *) e + s; s++; |
|
... |
... |
static void *my_mysqli_close(struct zend_execute_data *e, struct zval *retv) |
1146 |
1146 |
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
1147 |
1147 |
|
|
1148 |
1148 |
unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
1149 |
|
struct zval *para = (struct zval *) e + s; |
|
1150 |
1149 |
c.type = 'M'; |
c.type = 'M'; |
1151 |
1150 |
|
|
1152 |
1151 |
// link |
// link |
|
... |
... |
static void *my_mysqli_close(struct zend_execute_data *e, struct zval *retv) |
1172 |
1171 |
return ret; |
return ret; |
1173 |
1172 |
} |
} |
1174 |
1173 |
|
|
|
1174 |
|
void *(*old_mysqli_fetch_all)(struct zend_execute_data *, struct zval *); |
|
1175 |
|
static void *my_mysqli_fetch_all(struct zend_execute_data *e, struct zval *retv) |
|
1176 |
|
{ |
|
1177 |
|
struct query q; |
|
1178 |
|
|
|
1179 |
|
unsigned int num_args = e->This.u2.num_args; |
|
1180 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
1181 |
|
|
|
1182 |
|
unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
|
1183 |
|
q.type = 'M'; |
|
1184 |
|
|
|
1185 |
|
// res |
|
1186 |
|
struct zval *z = (struct zval *) e + s; s++; |
|
1187 |
|
php_zval_dump(" res: ", z); |
|
1188 |
|
q.res = z->value.p; |
|
1189 |
|
|
|
1190 |
|
// mode |
|
1191 |
|
if (num_args >= 2) { |
|
1192 |
|
z = (struct zval *) e + s; s++; |
|
1193 |
|
q.mode = z->value.lval; |
|
1194 |
|
xlog(50, " mode=0x%lx\n", q.mode); |
|
1195 |
|
} else { |
|
1196 |
|
q.mode = 2; // MYSQLI_NUM |
|
1197 |
|
} |
|
1198 |
|
|
|
1199 |
|
ninedogs_process_db("mysqli_fetch_all", NINEDOGS_DB_FETCH_START, &q); |
|
1200 |
|
void *ret = old_mysqli_fetch_all(e, retv); |
|
1201 |
|
if (!retv) |
|
1202 |
|
return ret; |
|
1203 |
|
php_zval_dump(" retv: ", retv); |
|
1204 |
|
|
|
1205 |
|
if (retv->u1.v.type == 7) { // array |
|
1206 |
|
struct zend_array *a = retv->value.arr; |
|
1207 |
|
q.num = a->nNumUsed; |
|
1208 |
|
//q.ret = 0; |
|
1209 |
|
// TODO php_mysqli_set_last_error(e, dbh, &qs); // TODO is qs.res set here? |
|
1210 |
|
// TODO: do we set num and aff? |
|
1211 |
|
} else if (retv->u1.v.type == 3) { // true (for queries not returning rows) |
|
1212 |
|
q.num = 0; |
|
1213 |
|
//q.ret = 1; |
|
1214 |
|
} |
|
1215 |
|
|
|
1216 |
|
ninedogs_process_db("mysqli_fetch_all", NINEDOGS_DB_FETCH_END, &q); |
|
1217 |
|
|
|
1218 |
|
return ret; |
|
1219 |
|
} |
|
1220 |
|
|
|
1221 |
|
void *(*old_mysqli_fetch_array)(struct zend_execute_data *, struct zval *); |
|
1222 |
|
static void *my_mysqli_fetch_array(struct zend_execute_data *e, struct zval *retv) |
|
1223 |
|
{ |
|
1224 |
|
struct query q; |
|
1225 |
|
|
|
1226 |
|
unsigned int num_args = e->This.u2.num_args; |
|
1227 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
1228 |
|
|
|
1229 |
|
unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
|
1230 |
|
q.type = 'M'; |
|
1231 |
|
|
|
1232 |
|
// res |
|
1233 |
|
struct zval *z = (struct zval *) e + s; s++; |
|
1234 |
|
php_zval_dump(" res: ", z); |
|
1235 |
|
q.res = z->value.p; |
|
1236 |
|
|
|
1237 |
|
// mode |
|
1238 |
|
if (num_args >= 2) { |
|
1239 |
|
z = (struct zval *) e + s; s++; |
|
1240 |
|
q.mode = z->value.lval; |
|
1241 |
|
xlog(50, " mode=0x%lx\n", q.mode); |
|
1242 |
|
} else { |
|
1243 |
|
q.mode = 3; // MYSQLI_BOTH |
|
1244 |
|
} |
|
1245 |
|
|
|
1246 |
|
ninedogs_process_db("mysqli_fetch_array", NINEDOGS_DB_FETCH_START, &q); |
|
1247 |
|
void *ret = old_mysqli_fetch_array(e, retv); |
|
1248 |
|
if (!retv) |
|
1249 |
|
return ret; |
|
1250 |
|
php_zval_dump(" retv: ", retv); |
|
1251 |
|
|
|
1252 |
|
if (retv->u1.v.type == 7) { // array |
|
1253 |
|
q.ret = 2; |
|
1254 |
|
} else if (retv->u1.v.type == 2) { // false - TODO set error |
|
1255 |
|
q.ret = 1; |
|
1256 |
|
} else { |
|
1257 |
|
q.ret = 0; |
|
1258 |
|
} |
|
1259 |
|
|
|
1260 |
|
ninedogs_process_db("mysqli_fetch_array", NINEDOGS_DB_FETCH_END, &q); |
|
1261 |
|
|
|
1262 |
|
return ret; |
|
1263 |
|
} |
|
1264 |
|
|
|
1265 |
|
void *(*old_mysqli_free_result)(struct zend_execute_data *, struct zval *); |
|
1266 |
|
static void *my_mysqli_free_result(struct zend_execute_data *e, struct zval *retv) |
|
1267 |
|
{ |
|
1268 |
|
struct free_result fr; |
|
1269 |
|
|
|
1270 |
|
unsigned int num_args = e->This.u2.num_args; |
|
1271 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
1272 |
|
|
|
1273 |
|
unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
|
1274 |
|
fr.type = 'M'; |
|
1275 |
|
|
|
1276 |
|
// res |
|
1277 |
|
struct zval *z = (struct zval *) e + s; s++; |
|
1278 |
|
php_zval_dump(" res: ", z); |
|
1279 |
|
fr.res = z->value.p; |
|
1280 |
|
|
|
1281 |
|
void *ret = old_mysqli_free_result(e, retv); |
|
1282 |
|
if (!retv) |
|
1283 |
|
return ret; |
|
1284 |
|
|
|
1285 |
|
fr.ok = 1; |
|
1286 |
|
ninedogs_process_db("mysqli_free_result", NINEDOGS_DB_FREE_RESULT, &fr); |
|
1287 |
|
|
|
1288 |
|
return ret; |
|
1289 |
|
} |
|
1290 |
|
|
|
1291 |
|
void *(*old_mysqli_stmt_execute)(struct zend_execute_data *, struct zval *); |
|
1292 |
|
static void *my_mysqli_stmt_execute(struct zend_execute_data *e, struct zval *retv) |
|
1293 |
|
{ |
|
1294 |
|
struct execute ex; |
|
1295 |
|
|
|
1296 |
|
unsigned int num_args = e->This.u2.num_args; |
|
1297 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
1298 |
|
|
|
1299 |
|
unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
|
1300 |
|
ex.type = 'M'; |
|
1301 |
|
ex.params.len = 0; |
|
1302 |
|
|
|
1303 |
|
// res |
|
1304 |
|
struct zval *z = (struct zval *) e + s; s++; |
|
1305 |
|
php_zval_dump(" stmt: ", z); |
|
1306 |
|
ex.stmt = z->value.p; |
|
1307 |
|
|
|
1308 |
|
if (num_args >= 2) { |
|
1309 |
|
z = (struct zval *) e + s; s++; |
|
1310 |
|
struct zend_array *za = z->value.arr; |
|
1311 |
|
zend_array_to_params_array(&ex.params, za); |
|
1312 |
|
} |
|
1313 |
|
|
|
1314 |
|
ninedogs_process_db("mysqli_stmt_execute", NINEDOGS_DB_EXECUTE_START, &ex); |
|
1315 |
|
void *ret = old_mysqli_stmt_execute(e, retv); |
|
1316 |
|
if (!retv) |
|
1317 |
|
return ret; |
|
1318 |
|
|
|
1319 |
|
if (retv->u1.v.type == 3) { // true |
|
1320 |
|
ex.ret = 1; |
|
1321 |
|
} else if (retv->u1.v.type == 2) { // false |
|
1322 |
|
ex.ret = 0; |
|
1323 |
|
} |
|
1324 |
|
|
|
1325 |
|
ninedogs_process_db("mysqli_stmt_execute", NINEDOGS_DB_EXECUTE_END, &ex); |
|
1326 |
|
|
|
1327 |
|
return ret; |
|
1328 |
|
} |
|
1329 |
|
|
|
1330 |
|
void *(*old_mysqli_prepare)(struct zend_execute_data *, struct zval *); |
|
1331 |
|
static void *my_mysqli_prepare(struct zend_execute_data *e, struct zval *retv) |
|
1332 |
|
{ |
|
1333 |
|
struct prepare p; |
|
1334 |
|
|
|
1335 |
|
unsigned int num_args = e->This.u2.num_args; |
|
1336 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
1337 |
|
|
|
1338 |
|
unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
|
1339 |
|
p.type = 'M'; |
|
1340 |
|
|
|
1341 |
|
// link |
|
1342 |
|
struct zval *z = (struct zval *) e + s; s++; |
|
1343 |
|
php_zval_dump(" link: ", z); |
|
1344 |
|
p.dbh = z->value.p; |
|
1345 |
|
|
|
1346 |
|
// query |
|
1347 |
|
z = (struct zval *) e + s; s++; |
|
1348 |
|
struct zend_string *xs = z->value.str; |
|
1349 |
|
xlog(50, " query=%s\n", xs->val); |
|
1350 |
|
p.q = xs->val; |
|
1351 |
|
p.q_len = xs->len; |
|
1352 |
|
|
|
1353 |
|
ninedogs_process_db("mysqli_prepare", NINEDOGS_DB_PREPARE_START, &p); |
|
1354 |
|
void *ret = old_mysqli_prepare(e, retv); |
|
1355 |
|
if (!retv) |
|
1356 |
|
return ret; |
|
1357 |
|
php_zval_dump(" retv: ", retv); |
|
1358 |
|
|
|
1359 |
|
// PHP7 returns resource, PHP8.1 returns object |
|
1360 |
|
if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { |
|
1361 |
|
p.stmt = retv->value.p; |
|
1362 |
|
} else if (retv->u1.v.type == 2) { // false |
|
1363 |
|
p.stmt = NULL; |
|
1364 |
|
} |
|
1365 |
|
|
|
1366 |
|
ninedogs_process_db("mysqli_prepare", NINEDOGS_DB_PREPARE_END, &p); |
|
1367 |
|
|
|
1368 |
|
return ret; |
|
1369 |
|
} |
|
1370 |
|
|
|
1371 |
|
void *(*old_mysqli_stmt_prepare)(struct zend_execute_data *, struct zval *); |
|
1372 |
|
static void *my_mysqli_stmt_prepare(struct zend_execute_data *e, struct zval *retv) |
|
1373 |
|
{ |
|
1374 |
|
struct prepare p; |
|
1375 |
|
|
|
1376 |
|
unsigned int num_args = e->This.u2.num_args; |
|
1377 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
1378 |
|
|
|
1379 |
|
unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
|
1380 |
|
p.type = 'M'; |
|
1381 |
|
|
|
1382 |
|
// stmt |
|
1383 |
|
struct zval *z = (struct zval *) e + s; s++; |
|
1384 |
|
php_zval_dump(" stmt: ", z); |
|
1385 |
|
p.stmt = z->value.p; |
|
1386 |
|
|
|
1387 |
|
// query |
|
1388 |
|
z = (struct zval *) e + s; s++; |
|
1389 |
|
struct zend_string *xs = z->value.str; |
|
1390 |
|
xlog(50, " query=%s\n", xs->val); |
|
1391 |
|
p.q = xs->val; |
|
1392 |
|
p.q_len = xs->len; |
|
1393 |
|
|
|
1394 |
|
ninedogs_process_db("mysqli_stmt_prepare", NINEDOGS_DB_PREPARE_START, &p); |
|
1395 |
|
void *ret = old_mysqli_stmt_prepare(e, retv); |
|
1396 |
|
if (!retv) |
|
1397 |
|
return ret; |
|
1398 |
|
php_zval_dump(" retv: ", retv); |
|
1399 |
|
|
|
1400 |
|
if (retv->u1.v.type == 3) { // true |
|
1401 |
|
p.ret = 1; |
|
1402 |
|
} else if (retv->u1.v.type == 2) { // false |
|
1403 |
|
p.ret = 0; |
|
1404 |
|
} |
|
1405 |
|
|
|
1406 |
|
ninedogs_process_db("mysqli_stmt_prepare", NINEDOGS_DB_PREPARE_END, &p); |
|
1407 |
|
|
|
1408 |
|
return ret; |
|
1409 |
|
} |
|
1410 |
|
|
|
1411 |
|
void *(*old_mysqli_autocommit)(struct zend_execute_data *, struct zval *); |
|
1412 |
|
static void *my_mysqli_autocommit(struct zend_execute_data *e, struct zval *retv) |
|
1413 |
|
{ |
|
1414 |
|
struct db_autocommit a; |
|
1415 |
|
|
|
1416 |
|
unsigned int num_args = e->This.u2.num_args; |
|
1417 |
|
xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args); |
|
1418 |
|
|
|
1419 |
|
unsigned int s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval); |
|
1420 |
|
a.type = 'M'; |
|
1421 |
|
|
|
1422 |
|
// link |
|
1423 |
|
struct zval *z = (struct zval *) e + s; s++; |
|
1424 |
|
a.link = z->value.p; |
|
1425 |
|
|
|
1426 |
|
z = (struct zval *) e + s; s++; |
|
1427 |
|
php_zval_dump(" bool: ", z); |
|
1428 |
|
a.value = z->u1.v.type == 3; |
|
1429 |
|
|
|
1430 |
|
ninedogs_process_db("mysqli_autocommit", NINEDOGS_DB_AUTOCOMMIT_START, &a); |
|
1431 |
|
void *ret = old_mysqli_autocommit(e, retv); |
|
1432 |
|
if (!retv) |
|
1433 |
|
return ret; |
|
1434 |
|
|
|
1435 |
|
if (retv->u1.v.type == 3) { // true |
|
1436 |
|
a.ret = 1; |
|
1437 |
|
} else if (retv->u1.v.type == 2) { // false |
|
1438 |
|
a.ret = 0; |
|
1439 |
|
} |
|
1440 |
|
|
|
1441 |
|
ninedogs_process_db("mysqli_autocommit", NINEDOGS_DB_AUTOCOMMIT_END, &a); |
|
1442 |
|
|
|
1443 |
|
return ret; |
|
1444 |
|
} |
|
1445 |
|
|
|
1446 |
|
|
1175 |
1447 |
|
|
1176 |
1448 |
struct zend_module_entry *(*old_get_module)(void); |
struct zend_module_entry *(*old_get_module)(void); |
1177 |
1449 |
static struct zend_module_entry *php_hook_get_module_func(void) |
static struct zend_module_entry *php_hook_get_module_func(void) |
|
... |
... |
static struct zend_module_entry *php_hook_get_module_func(void) |
1226 |
1498 |
|
|
1227 |
1499 |
fe = new->functions; |
fe = new->functions; |
1228 |
1500 |
while (fe && fe->fname) { |
while (fe && fe->fname) { |
1229 |
|
xlog(2, " fe=%p\n", fe); |
|
1230 |
1501 |
xlog(100, " func %s handler=%p\n", fe->fname, fe->handler); |
xlog(100, " func %s handler=%p\n", fe->fname, fe->handler); |
1231 |
1502 |
if (strncmp(fe->fname, "pg_", 3) == 0) { |
if (strncmp(fe->fname, "pg_", 3) == 0) { |
1232 |
1503 |
if (strcmp(fe->fname, "pg_close") == 0) { |
if (strcmp(fe->fname, "pg_close") == 0) { |
|
... |
... |
static struct zend_module_entry *php_hook_get_module_func(void) |
1268 |
1539 |
xlog(100, " %s: do not hook [%s]!\n", __func__, fe->fname); |
xlog(100, " %s: do not hook [%s]!\n", __func__, fe->fname); |
1269 |
1540 |
} |
} |
1270 |
1541 |
} else if (strncmp(fe->fname, "mysqli_", 7) == 0) { |
} else if (strncmp(fe->fname, "mysqli_", 7) == 0) { |
1271 |
|
if (strcmp(fe->fname, "mysqli_close") == 0) { |
|
|
1542 |
|
if (strcmp(fe->fname, "mysqli_autocommit") == 0) { |
|
1543 |
|
old_mysqli_autocommit = fe->handler; |
|
1544 |
|
fe->handler = my_mysqli_autocommit; |
|
1545 |
|
} else if (strcmp(fe->fname, "mysqli_close") == 0) { |
1272 |
1546 |
old_mysqli_close = fe->handler; |
old_mysqli_close = fe->handler; |
1273 |
1547 |
fe->handler = my_mysqli_close; |
fe->handler = my_mysqli_close; |
1274 |
1548 |
} else if (strcmp(fe->fname, "mysqli_connect") == 0) { |
} else if (strcmp(fe->fname, "mysqli_connect") == 0) { |
1275 |
1549 |
old_mysqli_connect = fe->handler; |
old_mysqli_connect = fe->handler; |
1276 |
1550 |
fe->handler = my_mysqli_connect; |
fe->handler = my_mysqli_connect; |
|
1551 |
|
} else if (strcmp(fe->fname, "mysqli_fetch_all") == 0) { |
|
1552 |
|
old_mysqli_fetch_all = fe->handler; |
|
1553 |
|
fe->handler = my_mysqli_fetch_all; |
|
1554 |
|
} else if (strcmp(fe->fname, "mysqli_fetch_array") == 0) { |
|
1555 |
|
old_mysqli_fetch_array = fe->handler; |
|
1556 |
|
fe->handler = my_mysqli_fetch_array; |
|
1557 |
|
} else if (strcmp(fe->fname, "mysqli_free_result") == 0) { |
|
1558 |
|
old_mysqli_free_result = fe->handler; |
|
1559 |
|
fe->handler = my_mysqli_free_result; |
1277 |
1560 |
} else if (strcmp(fe->fname, "mysqli_query") == 0) { |
} else if (strcmp(fe->fname, "mysqli_query") == 0) { |
1278 |
1561 |
old_mysqli_query = fe->handler; |
old_mysqli_query = fe->handler; |
1279 |
1562 |
fe->handler = my_mysqli_query; |
fe->handler = my_mysqli_query; |
|
1563 |
|
} else if (strcmp(fe->fname, "mysqli_prepare") == 0) { |
|
1564 |
|
old_mysqli_prepare = fe->handler; |
|
1565 |
|
fe->handler = my_mysqli_prepare; |
1280 |
1566 |
} else if (strcmp(fe->fname, "mysqli_real_connect") == 0) { |
} else if (strcmp(fe->fname, "mysqli_real_connect") == 0) { |
1281 |
1567 |
old_mysqli_real_connect = fe->handler; |
old_mysqli_real_connect = fe->handler; |
1282 |
1568 |
fe->handler = my_mysqli_real_connect; |
fe->handler = my_mysqli_real_connect; |
|
1569 |
|
} else if (strcmp(fe->fname, "mysqli_stmt_execute") == 0) { |
|
1570 |
|
old_mysqli_stmt_execute = fe->handler; |
|
1571 |
|
fe->handler = my_mysqli_stmt_execute; |
|
1572 |
|
} else if (strcmp(fe->fname, "mysqli_stmt_prepare") == 0) { |
|
1573 |
|
old_mysqli_stmt_prepare = fe->handler; |
|
1574 |
|
fe->handler = my_mysqli_stmt_prepare; |
1283 |
1575 |
} else { |
} else { |
1284 |
1576 |
xlog(100, " %s: do not hook [%s]!\n", __func__, fe->fname); |
xlog(100, " %s: do not hook [%s]!\n", __func__, fe->fname); |
1285 |
1577 |
} |
} |
File trace/nd-trace.c changed (mode: 100644) (index 03197de..4725370) |
... |
... |
static uint8_t decode_bool(const char *prefix, char *out, size_t out_size, |
83 |
83 |
unsigned char *d, unsigned int *i) |
unsigned char *d, unsigned int *i) |
84 |
84 |
{ |
{ |
85 |
85 |
uint8_t v = d[*i]; *i = *i + 1; |
uint8_t v = d[*i]; *i = *i + 1; |
86 |
|
snprintf(out, out_size, "%s%s", prefix, v == 0 ? "NOK" : "OK"); |
|
|
86 |
|
snprintf(out, out_size, "%s%s", prefix, v == 0 ? "nok" : "ok"); |
87 |
87 |
return v; |
return v; |
88 |
88 |
} |
} |
89 |
89 |
|
|
|
... |
... |
static int decode_sqlite3_ret(char *out, unsigned out_size, |
645 |
645 |
return ret; |
return ret; |
646 |
646 |
} |
} |
647 |
647 |
|
|
|
648 |
|
static int decode_sqlite3_open_flags(char *out, unsigned out_size, |
|
649 |
|
unsigned char *d, unsigned int *i) |
|
650 |
|
{ |
|
651 |
|
unsigned int ret = decode32(d, i); |
|
652 |
|
|
|
653 |
|
char *a = ""; if (ret & 0x00000001) a = "|READONLY"; |
|
654 |
|
char *b = ""; if (ret & 0x00000002) b = "|READWRITE"; |
|
655 |
|
char *c = ""; if (ret & 0x00000004) c = "|CREATE"; |
|
656 |
|
char *e = ""; if (ret & 0x00000008) e = "|DELETEONCLOSE"; |
|
657 |
|
char *f = ""; if (ret & 0x00000010) f = "|EXCLUSIVE"; |
|
658 |
|
char *g = ""; if (ret & 0x00000020) g = "|AUTOPROXY"; |
|
659 |
|
char *h = ""; if (ret & 0x00000040) h = "|URI"; |
|
660 |
|
char *j = ""; if (ret & 0x00000080) j = "|MEMORY"; |
|
661 |
|
char *k = ""; if (ret & 0x00000100) k = "|MAIN_DB"; |
|
662 |
|
char *l = ""; if (ret & 0x00000200) l = "|TEMP_DB"; |
|
663 |
|
char *m = ""; if (ret & 0x00000400) m = "|TRANSIENT_DB"; |
|
664 |
|
char *n = ""; if (ret & 0x00000800) n = "|MAIN_JOURNAL"; |
|
665 |
|
char *o = ""; if (ret & 0x00001000) o = "|TEMP_JOURNAL"; |
|
666 |
|
char *p = ""; if (ret & 0x00002000) p = "|SUBJOURNAL"; |
|
667 |
|
char *q = ""; if (ret & 0x00004000) q = "|SUPER_JOURNAL"; |
|
668 |
|
char *r = ""; if (ret & 0x00008000) r = "|NOMUTEX"; |
|
669 |
|
char *s = ""; if (ret & 0x00010000) s = "|FULLMUTEX"; |
|
670 |
|
char *t = ""; if (ret & 0x00020000) t = "|SHAREDCACHE"; |
|
671 |
|
char *u = ""; if (ret & 0x00040000) u = "|PRIVATECACHE"; |
|
672 |
|
char *v = ""; if (ret & 0x00080000) v = "|WAL"; |
|
673 |
|
char *w = ""; if (ret & 0x00100000) w = "|NOFOLLOW"; |
|
674 |
|
|
|
675 |
|
snprintf(out, out_size, "0x%x%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", |
|
676 |
|
ret, a, b, c, e, f, g, h, j, k, l, m, n, o, p, q, r, s, t, u, v, w); |
|
677 |
|
|
|
678 |
|
return ret; |
|
679 |
|
} |
|
680 |
|
|
648 |
681 |
static int decode_mysql_real_connect_flags(char *out, unsigned out_size, |
static int decode_mysql_real_connect_flags(char *out, unsigned out_size, |
649 |
682 |
unsigned char *d, unsigned int *i) |
unsigned char *d, unsigned int *i) |
650 |
683 |
{ |
{ |
|
... |
... |
static int decode_mysql_real_connect_flags(char *out, unsigned out_size, |
657 |
690 |
char *interact = ""; if (ret & 1024) interact = "|INTERACTIVE"; |
char *interact = ""; if (ret & 1024) interact = "|INTERACTIVE"; |
658 |
691 |
char *ssl = ""; if (ret & 2048) ssl = "SSL"; |
char *ssl = ""; if (ret & 2048) ssl = "SSL"; |
659 |
692 |
|
|
660 |
|
snprintf(out, out_size, "%x%s%s%s%s%s%s", |
|
|
693 |
|
snprintf(out, out_size, "0x%x%s%s%s%s%s%s", |
661 |
694 |
ret, found_rows, compress, dont_ver, |
ret, found_rows, compress, dont_ver, |
662 |
695 |
ignore_space, interact, ssl); |
ignore_space, interact, ssl); |
663 |
696 |
|
|
|
... |
... |
static int decode_dlopen_flags(char *out, size_t out_size, |
677 |
710 |
char *noload = ""; if (ret & RTLD_NOLOAD) nodel = "|NOLOAD"; |
char *noload = ""; if (ret & RTLD_NOLOAD) nodel = "|NOLOAD"; |
678 |
711 |
char *deep = ""; if (ret & RTLD_DEEPBIND) deep = "|DEEPBIND"; |
char *deep = ""; if (ret & RTLD_DEEPBIND) deep = "|DEEPBIND"; |
679 |
712 |
|
|
680 |
|
snprintf(out, out_size, "%s%s%s%s%s%s%s", |
|
681 |
|
lazy, now, global, local, nodel, noload, deep); |
|
|
713 |
|
snprintf(out, out_size, "0x%x%s%s%s%s%s%s%s", |
|
714 |
|
ret, lazy, now, global, local, nodel, noload, deep); |
|
715 |
|
|
|
716 |
|
return ret; |
|
717 |
|
} |
|
718 |
|
|
|
719 |
|
static int decode_mysqli_mode(char *out, size_t out_size, |
|
720 |
|
unsigned char *d, unsigned int *i) |
|
721 |
|
{ |
|
722 |
|
int mode = decode32(d, i); |
|
723 |
|
|
|
724 |
|
if (mode == 1) |
|
725 |
|
snprintf(out, out_size, "MYSQLI_ASSOC"); |
|
726 |
|
else if (mode == 2) |
|
727 |
|
snprintf(out, out_size, "MYSQLI_NUM"); |
|
728 |
|
else if (mode == 3) |
|
729 |
|
snprintf(out, out_size, "MYSQLI_BOTH"); |
|
730 |
|
|
|
731 |
|
return mode; |
|
732 |
|
} |
|
733 |
|
|
|
734 |
|
static void decode_query_params(char *out, size_t out_size, |
|
735 |
|
unsigned char *d, unsigned int *i) |
|
736 |
|
{ |
|
737 |
|
size_t len, rest = out_size - 1 - 1; // -1 for \0 and -1 for '}' |
|
738 |
|
|
|
739 |
|
uint16_t params_len = decode16(d, i); |
|
740 |
|
if (params_len == 0) { |
|
741 |
|
out[0] = '\0'; |
|
742 |
|
return; |
|
743 |
|
} |
|
744 |
|
|
|
745 |
|
if (rest >= 2) { |
|
746 |
|
strcpy(out, " {"); |
|
747 |
|
rest -= 2; |
|
748 |
|
} |
|
749 |
|
|
|
750 |
|
char *add = ""; |
|
751 |
|
for (unsigned short j = 0; j < params_len; j++) { |
|
752 |
|
char value[64]; |
|
753 |
|
uint8_t type = decode8(d, i); |
|
754 |
|
if (type == 1) { // long |
|
755 |
|
snprintf(value, sizeof(value), |
|
756 |
|
"%hu:long:%ld", j + 1, decode64(d, i)); |
|
757 |
|
} else if (type == 2) { // double |
|
758 |
|
snprintf(value, sizeof(value), |
|
759 |
|
"%hu:double:%f", j + 1, (double) decode64(d, i)); |
|
760 |
|
} else if (type == 3) { // string |
|
761 |
|
uint16_t len = decode16(d, i); |
|
762 |
|
char s[len * 4 + 1]; |
|
763 |
|
bin2hex_ascii(s, d + *i, len); *i = *i + len; |
|
764 |
|
snprintf(value, sizeof(value), |
|
765 |
|
"%hu:str:'%s'", j + 1, s); |
|
766 |
|
} |
|
767 |
|
|
|
768 |
|
len = 2 + strlen(value); |
|
769 |
|
if (len > rest) |
|
770 |
|
break; |
|
771 |
|
|
|
772 |
|
strcat(out, add); |
|
773 |
|
strcat(out, value); |
|
774 |
|
add = ", "; |
|
775 |
|
rest -= len; |
|
776 |
|
} |
|
777 |
|
|
|
778 |
|
strcat(out, "}"); |
|
779 |
|
} |
|
780 |
|
|
|
781 |
|
static int decode_h_errno(char *out, const size_t out_size, unsigned char *d, unsigned int *i) |
|
782 |
|
{ |
|
783 |
|
int ret = decode32(d, i); |
|
784 |
|
|
|
785 |
|
switch (ret) { |
|
786 |
|
case HOST_NOT_FOUND: snprintf(out, out_size, "HOST_NOT_FOUND"); break; |
|
787 |
|
case NO_DATA: snprintf(out, out_size, "NO_DATA"); break; |
|
788 |
|
case NO_RECOVERY: snprintf(out, out_size, "NO_RECOVERY"); break; |
|
789 |
|
case TRY_AGAIN: snprintf(out, out_size, "TRY_AGAIN"); break; |
|
790 |
|
default: snprintf(out, out_size, "todd(%d)", ret); |
|
791 |
|
} |
682 |
792 |
|
|
683 |
793 |
return ret; |
return ret; |
684 |
794 |
} |
} |
685 |
795 |
|
|
|
796 |
|
static void decode_hostent(char *out, const size_t out_size, unsigned char *d, unsigned int *i) |
|
797 |
|
{ |
|
798 |
|
uint8_t len = decode8(d, i); |
|
799 |
|
char name[len * 4 + 1]; |
|
800 |
|
bin2hex_ascii(name, d + *i, len); *i = *i + len; |
|
801 |
|
|
|
802 |
|
char aliases[512] = {0}; char *add = ""; |
|
803 |
|
for (int j = 0; ; j++) { |
|
804 |
|
uint8_t alen = decode8(d, i); |
|
805 |
|
if (alen == 0) |
|
806 |
|
break; |
|
807 |
|
|
|
808 |
|
char alias[alen * 4 + 1]; |
|
809 |
|
bin2hex_ascii(alias, d + *i, alen); *i = *i + alen; |
|
810 |
|
strcat(aliases, add); add = ","; |
|
811 |
|
strcat(aliases, alias); |
|
812 |
|
} |
|
813 |
|
|
|
814 |
|
uint8_t addrtype = decode8(d, i); |
|
815 |
|
uint8_t h_length = decode8(d, i); |
|
816 |
|
uint8_t count = decode8(d, i); |
|
817 |
|
char addrs[512] = {0}; add = ""; |
|
818 |
|
for (int j = 0; j < count; j++) { |
|
819 |
|
char addr[40]; |
|
820 |
|
const char *r = inet_ntop(addrtype, d + *i, addr, sizeof(addr)); |
|
821 |
|
if (!r) |
|
822 |
|
bin2hex(addr, d + *i, h_length); |
|
823 |
|
*i = *i + h_length; |
|
824 |
|
strcat(addrs, add); add = ", "; |
|
825 |
|
strcat(addrs, addr); |
|
826 |
|
} |
|
827 |
|
|
|
828 |
|
snprintf(out, out_size, " => name=[%s] aliases={%s} addrs={%s}", |
|
829 |
|
name, aliases, addrs); |
|
830 |
|
} |
|
831 |
|
|
686 |
832 |
static void decode_func(const uint32_t parent, unsigned char *d) |
static void decode_func(const uint32_t parent, unsigned char *d) |
687 |
833 |
{ |
{ |
688 |
834 |
unsigned int i = 0; |
unsigned int i = 0; |
|
... |
... |
static void decode_func(const uint32_t parent, unsigned char *d) |
827 |
973 |
decode_ret_pointer(rest, sizeof(rest), d, &i); |
decode_ret_pointer(rest, sizeof(rest), d, &i); |
828 |
974 |
sprintf(line, "(%s, '%s', {%s}, 0x%x)%s", |
sprintf(line, "(%s, '%s', {%s}, 0x%x)%s", |
829 |
975 |
dirfd, pathname, sstat, flags, rest); |
dirfd, pathname, sstat, flags, rest); |
|
976 |
|
} else if ((strcmp(func, "fsync") == 0) |
|
977 |
|
|| (strcmp(func, "fdatasync") == 0)) { |
|
978 |
|
int fd = decode32(d, &i); |
|
979 |
|
if (type == 'r') |
|
980 |
|
decode_ret_int(rest, sizeof(rest), d, &i); |
|
981 |
|
sprintf(line, "(%d)%s", fd, rest); |
830 |
982 |
} break; |
} break; |
831 |
983 |
|
|
832 |
984 |
case 'g': |
case 'g': |
|
... |
... |
static void decode_func(const uint32_t parent, unsigned char *d) |
867 |
1019 |
if (type == 'r') |
if (type == 'r') |
868 |
1020 |
decode_ret_int(rest, sizeof(rest), d, &i); |
decode_ret_int(rest, sizeof(rest), d, &i); |
869 |
1021 |
sprintf(line, "('%s')%s", host, rest); |
sprintf(line, "('%s')%s", host, rest); |
|
1022 |
|
} else if (strcmp(func, "gethostbyname_r") == 0) { |
|
1023 |
|
uint16_t len = decode16(d, &i); |
|
1024 |
|
char host[len * 4 + 1]; |
|
1025 |
|
bin2hex_ascii(host, d + i, len); i += len; |
|
1026 |
|
if (type == 'r') { |
|
1027 |
|
int ret = decode32(d, &i); |
|
1028 |
|
if (ret == -1) |
|
1029 |
|
decode_h_errno(rest, sizeof(rest), d, &i); |
|
1030 |
|
else |
|
1031 |
|
decode_hostent(rest, sizeof(rest), d, &i); |
|
1032 |
|
} |
|
1033 |
|
sprintf(line, "('%s')%s", host, rest); |
870 |
1034 |
} else if (strcmp(func, "getrandom") == 0) { |
} else if (strcmp(func, "getrandom") == 0) { |
871 |
1035 |
size_t buflen = decode64(d, &i); |
size_t buflen = decode64(d, &i); |
872 |
1036 |
unsigned int flags = decode32(d, &i); |
unsigned int flags = decode32(d, &i); |
|
... |
... |
static void decode_func(const uint32_t parent, unsigned char *d) |
910 |
1074 |
} break; |
} break; |
911 |
1075 |
|
|
912 |
1076 |
case 'm': |
case 'm': |
913 |
|
if (strcmp(func, "mysqli_close") == 0) { |
|
|
1077 |
|
if (strcmp(func, "mysqli_autocommit") == 0) { |
|
1078 |
|
uint64_t link = decode64(d, &i); |
|
1079 |
|
uint8_t value = decode8(d, &i); |
|
1080 |
|
if (type == 'r') |
|
1081 |
|
decode_bool(" = ", rest, sizeof(rest), d, &i); |
|
1082 |
|
sprintf(line, "(link=0x%lx, %s)%s", |
|
1083 |
|
link, value == 0 ? "false" : "true", rest); |
|
1084 |
|
} else if (strcmp(func, "mysqli_close") == 0) { |
914 |
1085 |
uint64_t link = decode64(d, &i); |
uint64_t link = decode64(d, &i); |
915 |
1086 |
if (type == 'r') |
if (type == 'r') |
916 |
1087 |
decode_bool(" = ", rest, sizeof(rest), d, &i); |
decode_bool(" = ", rest, sizeof(rest), d, &i); |
|
... |
... |
static void decode_func(const uint32_t parent, unsigned char *d) |
923 |
1094 |
if (type == 'r') |
if (type == 'r') |
924 |
1095 |
decode_bool(" = ", rest, sizeof(rest), d, &i); |
decode_bool(" = ", rest, sizeof(rest), d, &i); |
925 |
1096 |
sprintf(line, "('%s')%s", cs, rest); |
sprintf(line, "('%s')%s", cs, rest); |
|
1097 |
|
} else if (strcmp(func, "mysqli_fetch_all") == 0) { |
|
1098 |
|
uint64_t res = decode64(d, &i); |
|
1099 |
|
char mode[64]; |
|
1100 |
|
decode_mysqli_mode(mode, sizeof(mode), d ,&i); |
|
1101 |
|
if (type == 'r') |
|
1102 |
|
snprintf(rest, sizeof(rest), " [%lu row(s)]", decode64(d, &i)); |
|
1103 |
|
sprintf(line, "(0x%lx, %s)%s", res, mode, rest); |
|
1104 |
|
} else if (strcmp(func, "mysqli_fetch_array") == 0) { |
|
1105 |
|
uint64_t res = decode64(d, &i); |
|
1106 |
|
char mode[64]; |
|
1107 |
|
decode_mysqli_mode(mode, sizeof(mode), d ,&i); |
|
1108 |
|
if (type == 'r') { |
|
1109 |
|
uint8_t ret = decode8(d, &i); |
|
1110 |
|
if (ret == 0) |
|
1111 |
|
snprintf(rest, sizeof(rest), " = no row"); |
|
1112 |
|
else if (ret == 1) |
|
1113 |
|
snprintf(rest, sizeof(rest), " = nok"); |
|
1114 |
|
else if (ret == 2) |
|
1115 |
|
snprintf(rest, sizeof(rest), " = ok"); |
|
1116 |
|
} |
|
1117 |
|
sprintf(line, "(0x%lx, %s)%s", res, mode, rest); |
|
1118 |
|
} else if (strcmp(func, "mysqli_free_result") == 0) { |
|
1119 |
|
uint64_t res = decode64(d, &i); |
|
1120 |
|
sprintf(line, "(0x%lx)", res); |
|
1121 |
|
} else if (strcmp(func, "mysqli_prepare") == 0) { |
|
1122 |
|
uint64_t link = decode64(d, &i); |
|
1123 |
|
uint16_t q_len = decode16(d, &i); |
|
1124 |
|
char q[q_len * 4 + 1]; |
|
1125 |
|
bin2hex_ascii(q, d + i, q_len); i += q_len; |
|
1126 |
|
if (type == 'r') { |
|
1127 |
|
uint64_t stmt = decode64(d, &i); |
|
1128 |
|
snprintf(rest, sizeof(rest), " = 0x%lx", stmt); |
|
1129 |
|
} |
|
1130 |
|
sprintf(line, "(link=0x%lx, '%s')%s", link, q, rest); |
926 |
1131 |
} else if (strcmp(func, "mysqli_query") == 0) { |
} else if (strcmp(func, "mysqli_query") == 0) { |
927 |
1132 |
uint64_t link = decode64(d, &i); |
uint64_t link = decode64(d, &i); |
928 |
1133 |
uint16_t q_len = decode16(d, &i); |
uint16_t q_len = decode16(d, &i); |
|
... |
... |
static void decode_func(const uint32_t parent, unsigned char *d) |
948 |
1153 |
if (type == 'r') |
if (type == 'r') |
949 |
1154 |
decode_bool(" = ", rest, sizeof(rest), d, &i); |
decode_bool(" = ", rest, sizeof(rest), d, &i); |
950 |
1155 |
sprintf(line, "(link=0x%lx, '%s', flags='%s')%s", link, cs, flags, rest); |
sprintf(line, "(link=0x%lx, '%s', flags='%s')%s", link, cs, flags, rest); |
|
1156 |
|
} else if (strcmp(func, "mysqli_stmt_execute") == 0) { |
|
1157 |
|
char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
|
1158 |
|
uint64_t stmt = decode64(d, &i); |
|
1159 |
|
if (type == 'c') { |
|
1160 |
|
decode_query_params(rest, sizeof(rest), d, &i); |
|
1161 |
|
sprintf(line, "(stmt=0x%lx%s%s)", |
|
1162 |
|
stmt, rest[0] ? ", " : "", rest); |
|
1163 |
|
} else if (type == 'r') { |
|
1164 |
|
uint8_t ret = decode8(d, &i); |
|
1165 |
|
if (ret == 1) |
|
1166 |
|
snprintf(rest, sizeof(rest), " = ok"); |
|
1167 |
|
else |
|
1168 |
|
snprintf(rest, sizeof(rest), " = nok"); |
|
1169 |
|
sprintf(line, "(stmt=0x%lx)%s", stmt, rest); |
|
1170 |
|
} |
|
1171 |
|
} else if (strcmp(func, "mysqli_stmt_prepare") == 0) { |
|
1172 |
|
uint64_t stmt = decode64(d, &i); |
|
1173 |
|
uint16_t q_len = decode16(d, &i); |
|
1174 |
|
char q[q_len * 4 + 1]; |
|
1175 |
|
bin2hex_ascii(q, d + i, q_len); i += q_len; |
|
1176 |
|
if (type == 'r') |
|
1177 |
|
decode_bool(" = ", rest, sizeof(rest), d, &i); |
|
1178 |
|
sprintf(line, "(stmt=0x%lx, '%s')%s", stmt, q, rest); |
951 |
1179 |
} break; |
} break; |
952 |
1180 |
|
|
953 |
1181 |
case 'n': |
case 'n': |
|
... |
... |
static void decode_func(const uint32_t parent, unsigned char *d) |
1010 |
1238 |
decode_ret_int(rest, sizeof(rest), d, &i); |
decode_ret_int(rest, sizeof(rest), d, &i); |
1011 |
1239 |
sprintf(line, "([%s], %u, %d)%s", |
sprintf(line, "([%s], %u, %d)%s", |
1012 |
1240 |
list, nf, timeout, rest); |
list, nf, timeout, rest); |
|
1241 |
|
} else if ((strcmp(func, "pread") == 0) |
|
1242 |
|
|| (strcmp(func, "pread64") == 0)) { |
|
1243 |
|
int fd = decode32(d, &i); |
|
1244 |
|
size_t count = decode64(d, &i); |
|
1245 |
|
off_t offset = decode64(d, &i); |
|
1246 |
|
if (type == 'c') { |
|
1247 |
|
sprintf(line, "(%d, buf, %zu, off=%zu)", fd, count, offset); |
|
1248 |
|
} else { |
|
1249 |
|
ssize_t ret = decode_ret_int64(rest, sizeof(rest), d, &i); |
|
1250 |
|
if (ret > 0) { |
|
1251 |
|
unsigned short max = decode16(d, &i); |
|
1252 |
|
char data[max * 4 + 1]; |
|
1253 |
|
bin2hex_ascii(data, d + i, max); i += max; |
|
1254 |
|
sprintf(line, "(%d, '%s'%s, %zu, off=%zu)%s", |
|
1255 |
|
fd, data, |
|
1256 |
|
max < ret ? "..." : "", count, offset, rest); |
|
1257 |
|
} else { |
|
1258 |
|
sprintf(line, "(%d, buf, %zu, off=%zu)%s", |
|
1259 |
|
fd, count, offset, rest); |
|
1260 |
|
} |
|
1261 |
|
} |
|
1262 |
|
} else if ((strcmp(func, "pwrite") == 0) |
|
1263 |
|
|| (strcmp(func, "pwrite64") == 0)) { |
|
1264 |
|
int fd = decode32(d, &i); |
|
1265 |
|
size_t count = decode64(d, &i); |
|
1266 |
|
off_t offset = decode64(d, &i); |
|
1267 |
|
if (type == 'c') { |
|
1268 |
|
unsigned short max = decode16(d, &i); |
|
1269 |
|
char data[max * 4 + 1]; |
|
1270 |
|
bin2hex_ascii(data, d + i, max); i += max; |
|
1271 |
|
sprintf(line, "(%d, '%s'%s, %zu, off=%zu)", |
|
1272 |
|
fd, data, |
|
1273 |
|
max < count ? "..." : "", count, offset); |
|
1274 |
|
} else { |
|
1275 |
|
decode_ret_int64(rest, sizeof(rest), d, &i); |
|
1276 |
|
sprintf(line, "(%d, buf, %zu, off=%zu)%s", |
|
1277 |
|
fd, count, offset, rest); |
|
1278 |
|
} |
1013 |
1279 |
} else if (strcmp(func, "pg_close") == 0) { |
} else if (strcmp(func, "pg_close") == 0) { |
1014 |
|
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
|
1015 |
1280 |
uint64_t h = decode64(d, &i); |
uint64_t h = decode64(d, &i); |
1016 |
|
sprintf(line, "(0x%lx)", h); |
|
|
1281 |
|
if (h == 0) |
|
1282 |
|
sprintf(line, "()"); |
|
1283 |
|
else |
|
1284 |
|
sprintf(line, "(0x%lx)", h); |
1017 |
1285 |
} else if ((strcmp(func, "pg_connect") == 0) |
} else if ((strcmp(func, "pg_connect") == 0) |
1018 |
1286 |
|| (strcmp(func, "pg_pconnect") == 0)) { |
|| (strcmp(func, "pg_pconnect") == 0)) { |
1019 |
1287 |
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
|
... |
... |
static void decode_func(const uint32_t parent, unsigned char *d) |
1038 |
1306 |
uint16_t q_len = decode16(d, &i); |
uint16_t q_len = decode16(d, &i); |
1039 |
1307 |
char q[q_len * 4 + 1]; |
char q[q_len * 4 + 1]; |
1040 |
1308 |
bin2hex_ascii(q, d + i, q_len); i += q_len; |
bin2hex_ascii(q, d + i, q_len); i += q_len; |
1041 |
|
while (type == 'c') { |
|
1042 |
|
uint16_t params_len = decode16(d, &i); |
|
1043 |
|
uint16_t max = decode16(d, &i); |
|
1044 |
|
if (max == 0) |
|
1045 |
|
break; |
|
1046 |
|
|
|
1047 |
|
// TODO: 'rest' may not be big enough! |
|
1048 |
|
strcpy(rest, " {"); |
|
1049 |
|
char *add = ""; |
|
1050 |
|
for (unsigned short j = 0; j < max; j++) { |
|
1051 |
|
char value[64]; |
|
1052 |
|
uint8_t type = decode8(d, &i); |
|
1053 |
|
if (type == 1) { // long |
|
1054 |
|
snprintf(value, sizeof(value), |
|
1055 |
|
"%hu:long:%ld", j + 1, decode64(d, &i)); |
|
1056 |
|
} else if (type == 2) { // double |
|
1057 |
|
snprintf(value, sizeof(value), |
|
1058 |
|
"%hu:double:%f", j + 1, (double) decode64(d, &i)); |
|
1059 |
|
} else if (type == 3) { // string |
|
1060 |
|
uint16_t len = decode16(d, &i); |
|
1061 |
|
char s[len * 4 + 1]; |
|
1062 |
|
bin2hex_ascii(s, d + i, len); i += len; |
|
1063 |
|
snprintf(value, sizeof(value), |
|
1064 |
|
"%hu:str:'%s'", j + 1, s); |
|
1065 |
|
} |
|
1066 |
|
|
|
1067 |
|
strcat(rest, add); |
|
1068 |
|
strcat(rest, value); |
|
1069 |
|
add = ", "; |
|
1070 |
|
} |
|
1071 |
|
if (max < params_len) |
|
1072 |
|
strcat(rest, "..."); |
|
1073 |
|
strcat(rest, "}"); |
|
1074 |
|
break; |
|
1075 |
|
} |
|
1076 |
|
if (type == 'r') { |
|
|
1309 |
|
if (type == 'c') { |
|
1310 |
|
decode_query_params(rest, sizeof(rest), d, &i); |
|
1311 |
|
} else if (type == 'r') { |
1077 |
1312 |
uint64_t res = decode64(d, &i); |
uint64_t res = decode64(d, &i); |
1078 |
1313 |
uint64_t rows = decode64(d, &i); |
uint64_t rows = decode64(d, &i); |
1079 |
1314 |
uint64_t aff = decode64(d, &i); |
uint64_t aff = decode64(d, &i); |
|
... |
... |
static void decode_func(const uint32_t parent, unsigned char *d) |
1100 |
1335 |
res, rows, aff); |
res, rows, aff); |
1101 |
1336 |
} |
} |
1102 |
1337 |
sprintf(line, "(h=0x%lx)%s", dbh, rest); |
sprintf(line, "(h=0x%lx)%s", dbh, rest); |
|
1338 |
|
} else if (strcmp(func, "pthread_attr_setstacksize") == 0) { |
|
1339 |
|
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
|
1340 |
|
uint64_t attr = decode64(d, &i); |
|
1341 |
|
size_t stack_size = decode64(d, &i); |
|
1342 |
|
decode_ret_int(rest, sizeof(rest), d, &i); |
|
1343 |
|
sprintf(line, "(attr=0x%lx, %zu)%s", |
|
1344 |
|
attr, stack_size, rest); |
|
1345 |
|
} else if (strcmp(func, "pthread_create") == 0) { |
|
1346 |
|
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
|
1347 |
|
uint64_t thread = decode64(d, &i); |
|
1348 |
|
uint64_t attr = decode64(d, &i); |
|
1349 |
|
uint64_t arg = decode64(d, &i); |
|
1350 |
|
decode_ret_int(rest, sizeof(rest), d, &i); |
|
1351 |
|
sprintf(line, "(thread=%lu, attr=0x%lx, arg=0x%lx)%s", |
|
1352 |
|
thread, attr, arg, rest); |
|
1353 |
|
} else if (strcmp(func, "pthread_setname_np") == 0) { |
|
1354 |
|
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
|
1355 |
|
uint64_t thread = decode64(d, &i); |
|
1356 |
|
uint16_t len = decode16(d, &i); |
|
1357 |
|
char name[len * 4 + 1]; |
|
1358 |
|
bin2hex_ascii(name, d + i, len); i += len; |
|
1359 |
|
decode_ret_int(rest, sizeof(rest), d, &i); |
|
1360 |
|
sprintf(line, "(thread=%lu, '%s')%s", |
|
1361 |
|
thread, name, rest); |
1103 |
1362 |
} break; |
} break; |
1104 |
1363 |
|
|
1105 |
1364 |
case 'r': |
case 'r': |
|
... |
... |
static void decode_func(const uint32_t parent, unsigned char *d) |
1212 |
1471 |
sprintf(line, "(%s, %s, %d)%s", |
sprintf(line, "(%s, %s, %d)%s", |
1213 |
1472 |
decode_socket_domain(xdomain), |
decode_socket_domain(xdomain), |
1214 |
1473 |
decode_socket_type(xtype), xprotocol, rest); |
decode_socket_type(xtype), xprotocol, rest); |
|
1474 |
|
} else if (strcmp(func, "sqlite3_bind_double") == 0) { |
|
1475 |
|
uint64_t stmt = decode64(d, &i); |
|
1476 |
|
int index = decode32(d, &i); |
|
1477 |
|
double value = decode64(d, &i); |
|
1478 |
|
decode_sqlite3_ret(rest, sizeof(rest), d, &i); |
|
1479 |
|
sprintf(line, "(0x%lx, index=%d, value=%f) = %s", |
|
1480 |
|
stmt, index, value, rest); |
|
1481 |
|
} else if (strcmp(func, "sqlite3_bind_int") == 0) { |
|
1482 |
|
uint64_t stmt = decode64(d, &i); |
|
1483 |
|
int index = decode32(d, &i); |
|
1484 |
|
int value = decode32(d, &i); |
|
1485 |
|
decode_sqlite3_ret(rest, sizeof(rest), d, &i); |
|
1486 |
|
sprintf(line, "(0x%lx, index=%d, value=%d) = %s", |
|
1487 |
|
stmt, index, value, rest); |
|
1488 |
|
} else if (strcmp(func, "sqlite3_bind_int64") == 0) { |
|
1489 |
|
uint64_t stmt = decode64(d, &i); |
|
1490 |
|
int index = decode32(d, &i); |
|
1491 |
|
int64_t value = decode64(d, &i); |
|
1492 |
|
decode_sqlite3_ret(rest, sizeof(rest), d, &i); |
|
1493 |
|
sprintf(line, "(0x%lx, index=%d, value=%ld) = %s", |
|
1494 |
|
stmt, index, value, rest); |
|
1495 |
|
} else if (strcmp(func, "sqlite3_bind_text") == 0) { |
|
1496 |
|
uint64_t stmt = decode64(d, &i); |
|
1497 |
|
int index = decode32(d, &i); |
|
1498 |
|
int16_t len = decode16(d, &i); |
|
1499 |
|
char value[len * 4 + 1]; |
|
1500 |
|
bin2hex_ascii(value, d + i, len); i += len; |
|
1501 |
|
decode_sqlite3_ret(rest, sizeof(rest), d, &i); |
|
1502 |
|
sprintf(line, "(stmt=0x%lx, index=%d, '%s') = %s", |
|
1503 |
|
stmt, index, value, rest); |
|
1504 |
|
} else if (strcmp(func, "sqlite3_finalize") == 0) { |
|
1505 |
|
uint64_t stmt = decode64(d, &i); |
|
1506 |
|
decode_sqlite3_ret(rest, sizeof(rest), d, &i); |
|
1507 |
|
sprintf(line, "(0x%lx)%s%s", stmt, rest[0] ? " = " : "", rest); |
1215 |
1508 |
} else if (strcmp(func, "sqlite3_open_v2") == 0) { |
} else if (strcmp(func, "sqlite3_open_v2") == 0) { |
1216 |
1509 |
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
//char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump); |
1217 |
1510 |
uint16_t filename_len = decode16(d, &i); |
uint16_t filename_len = decode16(d, &i); |
1218 |
1511 |
char filename[filename_len * 4 + 1]; |
char filename[filename_len * 4 + 1]; |
1219 |
1512 |
bin2hex_ascii(filename, d + i, filename_len); i += filename_len; |
bin2hex_ascii(filename, d + i, filename_len); i += filename_len; |
1220 |
|
int flags = decode32(d, &i); |
|
|
1513 |
|
char flags[128]; |
|
1514 |
|
decode_sqlite3_open_flags(flags, sizeof(flags), d, &i); |
1221 |
1515 |
uint16_t vfs_len = decode16(d, &i); |
uint16_t vfs_len = decode16(d, &i); |
1222 |
1516 |
char vfs[vfs_len * 4 + 1]; |
char vfs[vfs_len * 4 + 1]; |
1223 |
1517 |
bin2hex_ascii(vfs, d + i, vfs_len); i += vfs_len; |
bin2hex_ascii(vfs, d + i, vfs_len); i += vfs_len; |
1224 |
1518 |
|
|
1225 |
1519 |
if (type == 'c') { |
if (type == 'c') { |
1226 |
|
sprintf(line, "('%s', 0x%x, '%s')", |
|
|
1520 |
|
sprintf(line, "('%s', %s, '%s')", |
1227 |
1521 |
filename, flags, vfs); |
filename, flags, vfs); |
1228 |
1522 |
} else { |
} else { |
1229 |
1523 |
char err[64]; |
char err[64]; |
|
... |
... |
static void decode_func(const uint32_t parent, unsigned char *d) |
1231 |
1525 |
uint64_t pdb = 0; |
uint64_t pdb = 0; |
1232 |
1526 |
if (ret == 0) |
if (ret == 0) |
1233 |
1527 |
pdb = decode64(d, &i); |
pdb = decode64(d, &i); |
1234 |
|
sprintf(line, "('%s', 0x%lx, 0x%x, '%s') = %s", |
|
|
1528 |
|
sprintf(line, "('%s', 0x%lx, %s, '%s') = %s", |
1235 |
1529 |
filename, pdb, flags, vfs, err); |
filename, pdb, flags, vfs, err); |
1236 |
1530 |
} |
} |
1237 |
1531 |
} else if (strcmp(func, "sqlite3_prepare_v2") == 0) { |
} else if (strcmp(func, "sqlite3_prepare_v2") == 0) { |