List of commits:
Subject Hash Author Date (UTC)
A lot of small fixes 9a5841916f3f0870ca091f457102c7512b21808a Catalin(ux) M. BOIE 2022-11-23 07:28:06
Added pthread_join + small fixes a5206c335f8c858d791f114da7361190196ad4a4 Catalin(ux) M. BOIE 2022-11-21 14:05:31
Lots of updates 5583e8dbd607b684a14ced92b4d2ffdacbcf57e1 Catalin(ux) M. BOIE 2022-11-18 05:40:05
mysql, sqlite3, depth d9d83cafbd372d1055fa2e51cdf3deb2396f5d08 Catalin(ux) M. BOIE 2022-11-07 05:58:04
More spec fixes 3867b17137b5397c3eeabdcbbc232417ad212a27 Catalin(ux) M. BOIE 2022-10-25 19:04:28
More spec fixes 68abc4ce485fbbcc18a232e57b956f9e2b016d72 Catalin(ux) M. BOIE 2022-10-25 18:48:22
Fixed installation paths in Makefiles c98920bd55f7cd2ebcec7083e2360009d8c16b29 Catalin(ux) M. BOIE 2022-10-25 18:19:49
Debian support added, create correctly the paths for install 512c13ca06dda005504cdeab831431c943dde74a Catalin(ux) M. BOIE 2022-10-25 06:19:50
Bump version to 0.6 for a stupid reason (mass with dupdump) c4d10510ddf944965a80d9a3e5f4ac62b84a103e Catalin(ux) M. BOIE 2022-10-25 06:04:33
History update c83cd94af87636bc67bf9526ca0a65734ce96fac Catalin(ux) M. BOIE 2022-10-22 10:34:01
TODO update b1cbf0845dada017466763126d8569f62ace4cb4 Catalin(ux) M. BOIE 2022-10-22 08:20:20
Need libcap 4cdcd084fcf0e089e074aa0b090bc6f569a5d625 Catalin(ux) M. BOIE 2022-10-22 07:32:51
Removed BuildArch 54a76d595eb787edbd887d567eb5b29a6261cb4a Catalin(ux) M. BOIE 2022-10-21 18:51:41
Add 'catalinux+' for Conn d7b41a60e091fdd10aee5b45355c07896155853b Catalin(ux) M. BOIE 2022-10-21 18:39:11
We need Conn library d7412ea414a52fb289d70cc309dee8ceb5c5a67e Catalin(ux) M. BOIE 2022-10-21 16:12:03
spec: require gnutls and json-c f6378fc9cb10a110ae9d6826de0784de41ba4f72 Catalin(ux) M. BOIE 2022-10-21 15:20:07
More 'stat' related changes a94da02a9867f5a93d6d2098caf62b39541e36f1 Catalin(ux) M. BOIE 2022-10-21 14:56:48
Really first version (all files added) 0cf2be651bd2a2f93fe0af1c4bd56a11910791c5 Catalin(ux) M. BOIE 2022-10-21 12:48:38
First version d2839681f34f4760ac29dab2c6fa3f52544ed5af Catalin(ux) M. BOIE 2022-10-21 12:26:32
gnutls working, more js stuff cea2625f1129f2e6decb4947c18be31adedfe9e5 Catalin(ux) M. BOIE 2022-09-26 16:44:19
Commit 9a5841916f3f0870ca091f457102c7512b21808a - A lot of small fixes
Author: Catalin(ux) M. BOIE
Author date (UTC): 2022-11-23 07:28
Committer name: Catalin(ux) M. BOIE
Committer date (UTC): 2022-11-23 11:54
Parent(s): a5206c335f8c858d791f114da7361190196ad4a4
Signer:
Signing key:
Signing status: N
Tree: b36a3efe3158dc67a856e8e6af74e5edd3b97583
File Lines added Lines deleted
Makefile.in 5 1
agent/TODO 5 5
agent/ninedogs.c 21 5
agent/php.c 183 32
agent/process_db.c 11 17
agent/process_db.h 14 1
common/ids.h 2 0
debian/control 1 1
docs/Makefile 6 2
docs/pre1.tex 185 48
docs/pre1.txt 3 1
docs/spell_check.sh 10 0
ninedogs.spec 1 1
rocketgit/artifacts 5 0
test/php-container/Dockerfile 1 1
test/php-container/exec.sh 1 0
test/php-mysql/1.php 6 3
test/php-mysql/stmt_bind_param.php 36 0
test/php-mysql/stmt_bind_param.run 5 9
test/php-pg/1.php 2 0
test/php-pg/1.run 1 1
test/trace/syslog1.c 1 1
test/trace/syslog1.run 1 3
trace/nd-trace.c 42 10
File Makefile.in changed (mode: 100644) (index db32ace..b5ee3e3)
... ... export JSON_CFLAGS += $(shell pkg-config --cflags json-c)
14 14 export CFLAGSSO = $(CFLAGS) -ldl -shared -rdynamic -fPIC export CFLAGSSO = $(CFLAGS) -ldl -shared -rdynamic -fPIC
15 15
16 16
17 all: common agent ingestd webd trace
17 all: common agent ingestd webd trace doc
18 18
19 19
20 20 .PHONY: common .PHONY: common
 
... ... webd:
37 37 trace: trace:
38 38 make -R -C trace compile make -R -C trace compile
39 39
40 .PHONY: doc
41 doc:
42 make -R -C doc compile
43
40 44 .PHONY: install .PHONY: install
41 45 install: install:
42 46 @mkdir -p $(I_VAR_LOG)/ninedogs @mkdir -p $(I_VAR_LOG)/ninedogs
File agent/TODO changed (mode: 100644) (index d4cfcb4..17933fd)
... ... send q2 str
15 15 close conn close conn
16 16
17 17 == Random == == Random ==
18 [ ] mysqli_stmt_execute could show the value of the parameters
19 associated with mysqli_stmt_bind_param.
18 20 [ ] Add an identification for the pids attached, to store them in the log. [ ] Add an identification for the pids attached, to store them in the log.
19 21 [ ] Server message decoding is not working right I suspect. [ ] Server message decoding is not working right I suspect.
20 22 [ ] Investigate ltrace sources! [ ] Investigate ltrace sources!
 
... ... send q2 str
22 24 [ ] atexit/on_exit are not executed. [ ] atexit/on_exit are not executed.
23 25 [ ] Real-time see reads/writes from open files/disks. [ ] Real-time see reads/writes from open files/disks.
24 26 [ ] Catch also realloc (also for my allocator), calloc, mmap and munmap! [ ] Catch also realloc (also for my allocator), calloc, mmap and munmap!
25 [ ] Capture pthread_setname_np and append the info that ninedogs is there.
26 27 [ ] https://stackoverflow.com/questions/9232892/ld-preload-with-setuid-binary [ ] https://stackoverflow.com/questions/9232892/ld-preload-with-setuid-binary
27 28 I need to set the setuid bit for my .so. I need to set the setuid bit for my .so.
28 [ ] Allow ninedogs disabling by passing a kernel paramenter.
29 [ ] Allow ninedogs disabling by passing a kernel parameter.
29 30 [ ] man sysinfo [ ] man sysinfo
30 31 [ ] By whois, it seems we can get the domain expiration - report it. [ ] By whois, it seems we can get the domain expiration - report it.
31 32 Mostly for webservers. Mostly for webservers.
32 33 [ ] Can we report something about SPF/DKIM? [ ] Can we report something about SPF/DKIM?
33 34 [ ] Can we report something for DNSSEC? Key expiration? [ ] Can we report something for DNSSEC? Key expiration?
34 [ ] At stop, send a message with the error code. Also when SEGV.
35 [ ] When we force flush, we need to store how lont it was the interval. Do we have this?
35 [ ] When we force flush, we need to store how long it was the interval. Do we have this?
36 36 [ ] Record also the caller of the hijacked functions. [ ] Record also the caller of the hijacked functions.
37 37 [ ] Warn server if the number of file descriptors are close to the limit. [ ] Warn server if the number of file descriptors are close to the limit.
38 38 [ ] Send CPU information. [ ] Send CPU information.
39 [ ] Mangle all handlers.
39 [ ] Mangle all handlers values.
40 40 [ ] [ ]
41 41
42 42
File agent/ninedogs.c changed (mode: 100644) (index 4b3b3ea..3008734)
... ... static void my_trace_put64(unsigned char *buf, unsigned int *i, const uint64_t v
226 226
227 227 static void my_trace_put_double(unsigned char *buf, unsigned int *i, const double v) static void my_trace_put_double(unsigned char *buf, unsigned int *i, const double v)
228 228 { {
229 uint64_t u = htobe64(v);
230 memcpy(buf + *i, &u, 8); *i = *i + 8;
229 uint64_t u;
230 memcpy(&u, &v, 8);
231 my_trace_put64(buf, i, u);
231 232 } }
232 233
233 234 static void my_trace_put_bool(unsigned char *buf, unsigned int *i, const char v) static void my_trace_put_bool(unsigned char *buf, unsigned int *i, const char v)
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
647 648 my_trace_put64(buf, &i, (uint64_t) q->dbh); my_trace_put64(buf, &i, (uint64_t) q->dbh);
648 649 my_trace_put16(buf, &i, q->q_len); my_trace_put16(buf, &i, q->q_len);
649 650 my_trace_put(buf, &i, q->q, q->q_len); my_trace_put(buf, &i, q->q, q->q_len);
650 if (type == 'r')
651 if (type == 'r') {
651 652 my_trace_put64(buf, &i, (uint64_t) q->res); my_trace_put64(buf, &i, (uint64_t) q->res);
653 my_trace_put64(buf, &i, q->num);
654 my_trace_put64(buf, &i, q->aff);
655 }
652 656 } else if (strcmp(func, "mysqli_real_connect") == 0) { } else if (strcmp(func, "mysqli_real_connect") == 0) {
653 657 struct conn *c = va_arg(va, struct conn *); struct conn *c = va_arg(va, struct conn *);
654 658 my_trace_put64(buf, &i, (uint64_t) c->dbh); my_trace_put64(buf, &i, (uint64_t) c->dbh);
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
657 661 my_trace_put32(buf, &i, c->flags); my_trace_put32(buf, &i, c->flags);
658 662 if (type == 'r') if (type == 'r')
659 663 my_trace_put_bool(buf, &i, c->ret); my_trace_put_bool(buf, &i, c->ret);
664 } else if (strcmp(func, "mysqli_stmt_bind_param") == 0) {
665 struct nd_db_bind *b = va_arg(va, struct nd_db_bind *);
666 my_trace_put64(buf, &i, (uint64_t) b->stmt);
667 my_trace_put16(buf, &i, (uint16_t) b->types_len);
668 my_trace_put(buf, &i, b->types, b->types_len);
669 if (type == 'r')
670 my_trace_put_bool(buf, &i, b->ret);
660 671 } else if (strcmp(func, "mysqli_stmt_execute") == 0) { } else if (strcmp(func, "mysqli_stmt_execute") == 0) {
661 struct execute *e = va_arg(va, struct execute *);
672 struct nd_db_execute *e = va_arg(va, struct nd_db_execute *);
662 673 my_trace_put64(buf, &i, (uint64_t) e->stmt); my_trace_put64(buf, &i, (uint64_t) e->stmt);
663 674 if (type == 'c') { if (type == 'c') {
664 675 my_trace_put16(buf, &i, e->params.len); my_trace_put16(buf, &i, e->params.len);
 
... ... static unsigned int my_trace_encode(unsigned char *buf,
675 686 } }
676 687 } }
677 688 } }
678 if (type == 'r')
689 if (type == 'r') {
679 690 my_trace_put_bool(buf, &i, e->ret); my_trace_put_bool(buf, &i, e->ret);
691 if (e->ret == 1) {
692 my_trace_put64(buf, &i, e->num);
693 my_trace_put64(buf, &i, e->aff);
694 }
695 }
680 696 } else if (strcmp(func, "mysqli_stmt_prepare") == 0) { } else if (strcmp(func, "mysqli_stmt_prepare") == 0) {
681 697 struct prepare *p = va_arg(va, struct prepare *); struct prepare *p = va_arg(va, struct prepare *);
682 698 my_trace_put64(buf, &i, (uint64_t) p->stmt); my_trace_put64(buf, &i, (uint64_t) p->stmt);
File agent/php.c changed (mode: 100644) (index 547b340..c52cd55)
... ... static void zend_array_to_params_array(struct params_array *p, struct zend_array
353 353 xlog(101, " para: bs=%p h=%lu key=[%p] type %s: val: %s\n", xlog(101, " para: bs=%p h=%lu key=[%p] type %s: val: %s\n",
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 if (_z->u1.v.type == 4) {
356 if (_z->u1.v.type == 1) {
357 p->list[i].type = ND_PARAMS_TYPE_NULL;
358 } else if (_z->u1.v.type == 2) {
359 p->list[i].type = ND_PARAMS_TYPE_STRING;
360 p->list[i].str = "false";
361 p->list[i].length = 5;
362 } else if (_z->u1.v.type == 3) {
363 p->list[i].type = ND_PARAMS_TYPE_STRING;
364 p->list[i].str = "true";
365 p->list[i].length = 4;
366 } else if (_z->u1.v.type == 4) {
357 367 p->list[i].type = ND_PARAMS_TYPE_LONG; p->list[i].type = ND_PARAMS_TYPE_LONG;
358 368 p->list[i].l = _z->value.lval; p->list[i].l = _z->value.lval;
359 369 } else if (_z->u1.v.type == 5) { } else if (_z->u1.v.type == 5) {
 
... ... static void zend_array_to_params_array(struct params_array *p, struct zend_array
364 374 struct zend_string *zs = _z->value.str; struct zend_string *zs = _z->value.str;
365 375 p->list[i].str = zs->val; p->list[i].str = zs->val;
366 376 p->list[i].length = zs->len; p->list[i].length = zs->len;
377 } else {
378 p->list[i].type = ND_PARAMS_TYPE_NULL;
379 xlog(1, " I do not how to encode this type!\n");
367 380 } }
368 381
369 382 i++; i++;
 
... ... static void zend_array_to_params_array(struct params_array *p, struct zend_array
372 385 } }
373 386 } }
374 387
375 void *(*old_pg_last_error)(struct zend_execute_data *, struct zval *);
388 static void php_set_para(struct zend_execute_data *e, const unsigned int i,
389 const struct zval *para)
390 {
391 unsigned int s;
392 struct zval *dst;
393
394 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
395 dst = (struct zval *) e + s + i;
396 memcpy(dst, para, sizeof(struct zval));
397 }
398
399
400 static void *(*old_pg_last_error)(struct zend_execute_data *, struct zval *);
376 401 static void *my_pg_last_error(struct zend_execute_data *e, struct zval *retv) static void *my_pg_last_error(struct zend_execute_data *e, struct zval *retv)
377 402 { {
378 403 void *ret; void *ret;
 
... ... static void *my_pg_last_error(struct zend_execute_data *e, struct zval *retv)
385 410 ret = old_pg_last_error(e, retv); ret = old_pg_last_error(e, retv);
386 411 if (!retv) if (!retv)
387 412 return ret; return ret;
388
389 413 //php_zval_dump(" retv: ", retv); //php_zval_dump(" retv: ", retv);
390 414
391 415 return ret; return ret;
392 416 } }
393 417
394 void *(*old_pg_close)(struct zend_execute_data *, struct zval *);
418 static void *(*old_pg_close)(struct zend_execute_data *, struct zval *);
395 419 static void *my_pg_close(struct zend_execute_data *e, struct zval *retv) static void *my_pg_close(struct zend_execute_data *e, struct zval *retv)
396 420 { {
397 421 void *ret; void *ret;
 
... ... static void *my_pg_close(struct zend_execute_data *e, struct zval *retv)
419 443 return ret; return ret;
420 444 } }
421 445
422 void *(*old_pg_connect)(struct zend_execute_data *, struct zval *);
446 static void *(*old_pg_connect)(struct zend_execute_data *, struct zval *);
423 447 static void *my_pg_connect(struct zend_execute_data *e, struct zval *retv) static void *my_pg_connect(struct zend_execute_data *e, struct zval *retv)
424 448 { {
425 449 void *ret; void *ret;
 
... ... static void *my_pg_connect(struct zend_execute_data *e, struct zval *retv)
461 485 return ret; return ret;
462 486 } }
463 487
464 void *(*old_pg_pconnect)(struct zend_execute_data *, struct zval *);
488 static void *(*old_pg_pconnect)(struct zend_execute_data *, struct zval *);
465 489 static void *my_pg_pconnect(struct zend_execute_data *e, struct zval *retv) static void *my_pg_pconnect(struct zend_execute_data *e, struct zval *retv)
466 490 { {
467 491 void *ret; void *ret;
 
... ... static void *my_pg_pconnect(struct zend_execute_data *e, struct zval *retv)
501 525 return ret; return ret;
502 526 } }
503 527
504 void *(*old_pg_affected_rows)(struct zend_execute_data *, struct zval *);
528 static void *(*old_pg_affected_rows)(struct zend_execute_data *, struct zval *);
505 529
506 void *(*old_pg_free_result)(struct zend_execute_data *, struct zval *);
530 static void *(*old_pg_free_result)(struct zend_execute_data *, struct zval *);
507 531 static void *my_pg_free_result(struct zend_execute_data *e, struct zval *retv) static void *my_pg_free_result(struct zend_execute_data *e, struct zval *retv)
508 532 { {
509 533 void *ret; void *ret;
 
... ... static void *my_pg_free_result(struct zend_execute_data *e, struct zval *retv)
538 562 return ret; return ret;
539 563 } }
540 564
541 void *(*old_pg_num_rows)(struct zend_execute_data *, struct zval *);
565 static void *(*old_pg_num_rows)(struct zend_execute_data *, struct zval *);
542 566 static void *my_pg_num_rows(struct zend_execute_data *e, struct zval *retv) static void *my_pg_num_rows(struct zend_execute_data *e, struct zval *retv)
543 567 { {
544 568 void *ret; void *ret;
 
... ... static void *my_pg_num_rows(struct zend_execute_data *e, struct zval *retv)
557 581 return ret; return ret;
558 582 } }
559 583
560 static void php_set_para(struct zend_execute_data *e, const unsigned int i,
561 const struct zval *para)
562 {
563 unsigned int s;
564 struct zval *dst;
565
566 s = (sizeof(struct zend_execute_data) + sizeof(struct zval) - 1) / sizeof(struct zval);
567 dst = (struct zval *) e + s + i;
568 memcpy(dst, para, sizeof(struct zval));
569 }
570
571 584 static void php_pg_set_last_error(struct zend_execute_data *e, static void php_pg_set_last_error(struct zend_execute_data *e,
572 585 struct zval *dbh, struct query *q) struct zval *dbh, struct query *q)
573 586 { {
 
... ... static void php_pg_set_num_aff(struct zend_execute_data *e, struct zval *res,
615 628 q->aff = rz.value.lval; q->aff = rz.value.lval;
616 629 } }
617 630
618 void *(*old_pg_query)(struct zend_execute_data *, struct zval *);
631 static void *(*old_pg_query)(struct zend_execute_data *, struct zval *);
619 632 static void *my_pg_query(struct zend_execute_data *e, struct zval *retv) static void *my_pg_query(struct zend_execute_data *e, struct zval *retv)
620 633 { {
621 634 void *ret; void *ret;
 
... ... static void *my_pg_query(struct zend_execute_data *e, struct zval *retv)
678 691 return ret; return ret;
679 692 } }
680 693
681 void *(*old_pg_send_query)(struct zend_execute_data *, struct zval *);
694 static void *(*old_pg_send_query)(struct zend_execute_data *, struct zval *);
682 695 static void *my_pg_send_query(struct zend_execute_data *e, struct zval *retv) static void *my_pg_send_query(struct zend_execute_data *e, struct zval *retv)
683 696 { {
684 697 void *ret; void *ret;
 
... ... static void *my_pg_send_query(struct zend_execute_data *e, struct zval *retv)
728 741 } }
729 742
730 743 // TODO: not clear if on PHP 7 the parameter could be null // TODO: not clear if on PHP 7 the parameter could be null
731 void *(*old_pg_get_result)(struct zend_execute_data *, struct zval *);
744 static void *(*old_pg_get_result)(struct zend_execute_data *, struct zval *);
732 745 static void *my_pg_get_result(struct zend_execute_data *e, struct zval *retv) static void *my_pg_get_result(struct zend_execute_data *e, struct zval *retv)
733 746 { {
734 747 void *ret; void *ret;
 
... ... static void *my_pg_get_result(struct zend_execute_data *e, struct zval *retv)
780 793 return ret; return ret;
781 794 } }
782 795
783 void *(*old_pg_query_params)(struct zend_execute_data *, struct zval *);
796 static void *(*old_pg_query_params)(struct zend_execute_data *, struct zval *);
784 797 static void *my_pg_query_params(struct zend_execute_data *e, struct zval *retv) static void *my_pg_query_params(struct zend_execute_data *e, struct zval *retv)
785 798 { {
786 799 void *ret; void *ret;
 
... ... static void *my_pg_query_params(struct zend_execute_data *e, struct zval *retv)
849 862 return ret; return ret;
850 863 } }
851 864
852 void *(*old_pg_send_query_params)(struct zend_execute_data *, struct zval *);
865 static void *(*old_pg_send_query_params)(struct zend_execute_data *, struct zval *);
853 866 static void *my_pg_send_query_params(struct zend_execute_data *e, struct zval *retv) static void *my_pg_send_query_params(struct zend_execute_data *e, struct zval *retv)
854 867 { {
855 868 void *ret; void *ret;
 
... ... static void *my_pg_send_query_params(struct zend_execute_data *e, struct zval *r
903 916 } }
904 917
905 918
919
920 static void *(*old_mysqli_error)(struct zend_execute_data *, struct zval *);
921 static void *(*old_mysqli_affected_rows)(struct zend_execute_data *, struct zval *);
922 static void *(*old_mysqli_num_rows)(struct zend_execute_data *, struct zval *);
923 static void *(*old_mysqli_stmt_affected_rows)(struct zend_execute_data *, struct zval *);
924 static void *(*old_mysqli_stmt_num_rows)(struct zend_execute_data *, struct zval *);
925
926 static void php_mysqli_set_error(struct zend_execute_data *e,
927 struct zval *link, struct query *q)
928 {
929 struct zval rz;
930
931 e->This.u2.num_args = 1;
932 php_set_para(e, 0, link);
933
934 // TODO: we need also the numeric representation of the error!
935 xlog(50, " calling mysqli_error...\n");
936 old_mysqli_error(e, &rz);
937
938 if (rz.u1.v.type == 6) { // string
939 q->err = rz.value.str->val;
940 q->err_len = rz.value.str->len;
941 xlog(40, "%s: set error to [%s]\n", __func__, q->err);
942 } else {
943 q->err = "?";
944 q->err_len = 1;
945 }
946 }
947
948 static void php_mysqli_set_num_aff(struct zend_execute_data *e, struct zval *res,
949 struct query *q)
950 {
951 struct zval rz;
952
953 e->This.u2.num_args = 1;
954
955 //xlog(1, " calling old pg_affected_rows...\n");
956 //php_zed_dump(" e: ", e);
957 old_mysqli_affected_rows(e, &rz); // we need to pass a link here
958 php_zval_dump(" aff_rows: ", &rz);
959 q->aff = rz.value.lval;
960
961 php_set_para(e, 0, res);
962 //xlog(1, " calling old pg_num_rows...\n");
963 //php_zed_dump(" e: ", e);
964 old_mysqli_num_rows(e, &rz); // we need a result here
965 php_zval_dump(" num_rows: ", &rz);
966 q->num = rz.value.lval;
967 }
968
969 static void php_mysqli_stmt_set_num_aff(struct zend_execute_data *e,
970 struct nd_db_execute *q)
971 {
972 struct zval rz;
973
974 e->This.u2.num_args = 1;
975
976 //xlog(1, " calling old mysqli_stmt_affected_rows...\n");
977 //php_zed_dump(" e: ", e);
978 old_mysqli_stmt_affected_rows(e, &rz);
979 php_zval_dump(" aff_rows: ", &rz);
980 q->aff = rz.value.lval;
981
982 //xlog(1, " calling old mysqli_stmt_num_rows...\n");
983 //php_zed_dump(" e: ", e);
984 old_mysqli_stmt_num_rows(e, &rz);
985 php_zval_dump(" num_rows: ", &rz);
986 q->num = rz.value.lval;
987 }
988
906 989 void *(*old_mysqli_connect)(struct zend_execute_data *, struct zval *); void *(*old_mysqli_connect)(struct zend_execute_data *, struct zval *);
907 990 static void *my_mysqli_connect(struct zend_execute_data *e, struct zval *retv) static void *my_mysqli_connect(struct zend_execute_data *e, struct zval *retv)
908 991 { {
 
... ... static void *my_mysqli_query(struct zend_execute_data *e, struct zval *retv)
1115 1198 memcpy(&copy_para, para, sizeof(struct zval)); memcpy(&copy_para, para, sizeof(struct zval));
1116 1199
1117 1200 if (retv->u1.v.type == 2) { // false if (retv->u1.v.type == 2) { // false
1118 // TODO php_mysqli_set_last_error(e, dbh, &qs); // TODO is qs.res set here?
1201 // TODO php_mysqli_set_error(e, dbh, &qs); // TODO is qs.res set here?
1119 1202 // TODO: do we set num and aff? // TODO: do we set num and aff?
1120 1203 qs.res = (void *) 0; qs.res = (void *) 0;
1121 1204 } else if (retv->u1.v.type == 3) { // true (for queries not returning rows) } else if (retv->u1.v.type == 3) { // true (for queries not returning rows)
 
... ... static void *my_mysqli_query(struct zend_execute_data *e, struct zval *retv)
1123 1206 qs.res = (void *) 1; qs.res = (void *) 1;
1124 1207 } else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource } else if ((retv->u1.v.type == 8) || (retv->u1.v.type == 9)) { // object or resource
1125 1208 qs.res = retv->value.p; qs.res = retv->value.p;
1126 //TODO php_mysqli_set_num_aff(e, retv, &qs);
1209 php_mysqli_set_num_aff(e, retv, &qs);
1127 1210 do_restore = 1; do_restore = 1;
1128 1211 } }
1129 1212
 
... ... static void *my_mysqli_close(struct zend_execute_data *e, struct zval *retv)
1160 1243
1161 1244 if (retv->u1.v.type == 2) { // false if (retv->u1.v.type == 2) { // false
1162 1245 c.ret = 0; c.ret = 0;
1163 // TODO php_mysqli_set_last_error(e, dbh, &qs); // TODO is qs.res set here?
1246 // TODO php_mysqli_set_error(e, dbh, &qs); // TODO is qs.res set here?
1164 1247 // TODO: do we set num and aff? // TODO: do we set num and aff?
1165 1248 } else if (retv->u1.v.type == 3) { // true (for queries not returning rows) } else if (retv->u1.v.type == 3) { // true (for queries not returning rows)
1166 1249 c.ret = 1; c.ret = 1;
 
... ... static void *my_mysqli_fetch_all(struct zend_execute_data *e, struct zval *retv)
1202 1285 return ret; return ret;
1203 1286 php_zval_dump(" retv: ", retv); php_zval_dump(" retv: ", retv);
1204 1287
1288 // TODO php_mysqli_set_error(e, dbh, &qs); // TODO is qs.res set here?
1205 1289 if (retv->u1.v.type == 7) { // array if (retv->u1.v.type == 7) { // array
1206 1290 struct zend_array *a = retv->value.arr; struct zend_array *a = retv->value.arr;
1207 1291 q.num = a->nNumUsed; q.num = a->nNumUsed;
1208 1292 //q.ret = 0; //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?
1293 // TODO: do we set num and aff? Should we? We already count them in 'execute'.
1211 1294 } else if (retv->u1.v.type == 3) { // true (for queries not returning rows) } else if (retv->u1.v.type == 3) { // true (for queries not returning rows)
1212 1295 q.num = 0; q.num = 0;
1213 1296 //q.ret = 1; //q.ret = 1;
 
... ... static void *my_mysqli_free_result(struct zend_execute_data *e, struct zval *ret
1291 1374 void *(*old_mysqli_stmt_execute)(struct zend_execute_data *, struct zval *); void *(*old_mysqli_stmt_execute)(struct zend_execute_data *, struct zval *);
1292 1375 static void *my_mysqli_stmt_execute(struct zend_execute_data *e, struct zval *retv) static void *my_mysqli_stmt_execute(struct zend_execute_data *e, struct zval *retv)
1293 1376 { {
1294 struct execute ex;
1377 struct nd_db_execute ex;
1378 char do_restore = 0;
1295 1379
1296 1380 unsigned int num_args = e->This.u2.num_args; unsigned int num_args = e->This.u2.num_args;
1297 1381 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);
 
... ... static void *my_mysqli_stmt_execute(struct zend_execute_data *e, struct zval *re
1300 1384 ex.type = 'M'; ex.type = 'M';
1301 1385 ex.params.len = 0; ex.params.len = 0;
1302 1386
1303 // res
1387 struct zval *para = (struct zval *) e + s;
1388
1389 // stmt
1304 1390 struct zval *z = (struct zval *) e + s; s++; struct zval *z = (struct zval *) e + s; s++;
1305 1391 php_zval_dump(" stmt: ", z); php_zval_dump(" stmt: ", z);
1306 1392 ex.stmt = z->value.p; ex.stmt = z->value.p;
 
... ... static void *my_mysqli_stmt_execute(struct zend_execute_data *e, struct zval *re
1311 1397 zend_array_to_params_array(&ex.params, za); zend_array_to_params_array(&ex.params, za);
1312 1398 } }
1313 1399
1400 unsigned int copy_num_args = num_args;
1401 struct zval copy_para;
1402 memcpy(&copy_para, para, sizeof(struct zval));
1403
1314 1404 ninedogs_process_db("mysqli_stmt_execute", NINEDOGS_DB_EXECUTE_START, &ex); ninedogs_process_db("mysqli_stmt_execute", NINEDOGS_DB_EXECUTE_START, &ex);
1315 1405 void *ret = old_mysqli_stmt_execute(e, retv); void *ret = old_mysqli_stmt_execute(e, retv);
1316 1406 if (!retv) if (!retv)
 
... ... static void *my_mysqli_stmt_execute(struct zend_execute_data *e, struct zval *re
1318 1408
1319 1409 if (retv->u1.v.type == 3) { // true if (retv->u1.v.type == 3) { // true
1320 1410 ex.ret = 1; ex.ret = 1;
1411 php_mysqli_stmt_set_num_aff(e, &ex);
1412 do_restore = 1;
1321 1413 } else if (retv->u1.v.type == 2) { // false } else if (retv->u1.v.type == 2) { // false
1322 1414 ex.ret = 0; ex.ret = 0;
1323 1415 } }
1324 1416
1417 e->This.u2.num_args = copy_num_args;
1418 if (do_restore)
1419 memcpy(para, &copy_para, sizeof(struct zval));
1420
1325 1421 ninedogs_process_db("mysqli_stmt_execute", NINEDOGS_DB_EXECUTE_END, &ex); ninedogs_process_db("mysqli_stmt_execute", NINEDOGS_DB_EXECUTE_END, &ex);
1326 1422
1327 1423 return ret; return ret;
 
... ... static void *my_mysqli_autocommit(struct zend_execute_data *e, struct zval *retv
1443 1539 return ret; return ret;
1444 1540 } }
1445 1541
1542 void *(*old_mysqli_stmt_bind_param)(struct zend_execute_data *, struct zval *);
1543 static void *my_mysqli_stmt_bind_param(struct zend_execute_data *e, struct zval *retv)
1544 {
1545 struct nd_db_bind b;
1546
1547 unsigned int num_args = e->This.u2.num_args;
1548 xlog(100, "%s: e=%p num_args=%hu\n", __func__, e, num_args);
1549
1550 unsigned int s = (sizeof(struct zend_execute_data)
1551 + sizeof(struct zval) - 1) / sizeof(struct zval);
1552 b.type = 'M';
1553
1554 // stmt
1555 struct zval *z = (struct zval *) e + s; s++;
1556 //php_zval_dump(" stmt: ", z);
1557 b.stmt = z->value.p;
1558
1559 // types
1560 z = (struct zval *) e + s; s++;
1561 struct zend_string *xs = z->value.str;
1562 b.types = xs->val;
1563 b.types_len = xs->len;
1564
1565 ninedogs_process_db("mysqli_stmt_bind_param",
1566 NINEDOGS_DB_BIND_PARAM_START, &b);
1567 void *ret = old_mysqli_stmt_bind_param(e, retv);
1568 if (!retv)
1569 return ret;
1570
1571 if (retv->u1.v.type == 3) { // true
1572 b.ret = 1;
1573 } else if (retv->u1.v.type == 2) { // false
1574 b.ret = 0;
1575 }
1576
1577 ninedogs_process_db("mysqli_stmt_bind_param",
1578 NINEDOGS_DB_BIND_PARAM_END, &b);
1579
1580 return ret;
1581 }
1582
1583
1446 1584
1447 1585
1448 1586 struct zend_module_entry *(*old_get_module)(void); struct zend_module_entry *(*old_get_module)(void);
 
... ... static struct zend_module_entry *php_hook_get_module_func(void)
1545 1683 } else if (strcmp(fe->fname, "mysqli_close") == 0) { } else if (strcmp(fe->fname, "mysqli_close") == 0) {
1546 1684 old_mysqli_close = fe->handler; old_mysqli_close = fe->handler;
1547 1685 fe->handler = my_mysqli_close; fe->handler = my_mysqli_close;
1686 } else if (strcmp(fe->fname, "mysqli_affected_rows") == 0) {
1687 old_mysqli_stmt_affected_rows = fe->handler;
1548 1688 } else if (strcmp(fe->fname, "mysqli_connect") == 0) { } else if (strcmp(fe->fname, "mysqli_connect") == 0) {
1549 1689 old_mysqli_connect = fe->handler; old_mysqli_connect = fe->handler;
1550 1690 fe->handler = my_mysqli_connect; fe->handler = my_mysqli_connect;
1691 } else if (strcmp(fe->fname, "mysqli_error") == 0) {
1692 old_mysqli_error = fe->handler;
1551 1693 } else if (strcmp(fe->fname, "mysqli_fetch_all") == 0) { } else if (strcmp(fe->fname, "mysqli_fetch_all") == 0) {
1552 1694 old_mysqli_fetch_all = fe->handler; old_mysqli_fetch_all = fe->handler;
1553 1695 fe->handler = my_mysqli_fetch_all; fe->handler = my_mysqli_fetch_all;
 
... ... static struct zend_module_entry *php_hook_get_module_func(void)
1563 1705 } else if (strcmp(fe->fname, "mysqli_prepare") == 0) { } else if (strcmp(fe->fname, "mysqli_prepare") == 0) {
1564 1706 old_mysqli_prepare = fe->handler; old_mysqli_prepare = fe->handler;
1565 1707 fe->handler = my_mysqli_prepare; fe->handler = my_mysqli_prepare;
1708 } else if (strcmp(fe->fname, "mysqli_num_rows") == 0) {
1709 old_mysqli_num_rows = fe->handler;
1566 1710 } else if (strcmp(fe->fname, "mysqli_real_connect") == 0) { } else if (strcmp(fe->fname, "mysqli_real_connect") == 0) {
1567 1711 old_mysqli_real_connect = fe->handler; old_mysqli_real_connect = fe->handler;
1568 1712 fe->handler = my_mysqli_real_connect; fe->handler = my_mysqli_real_connect;
1713 } else if (strcmp(fe->fname, "mysqli_stmt_affected_rows") == 0) {
1714 old_mysqli_stmt_affected_rows = fe->handler;
1569 1715 } else if (strcmp(fe->fname, "mysqli_stmt_execute") == 0) { } else if (strcmp(fe->fname, "mysqli_stmt_execute") == 0) {
1570 1716 old_mysqli_stmt_execute = fe->handler; old_mysqli_stmt_execute = fe->handler;
1571 1717 fe->handler = my_mysqli_stmt_execute; fe->handler = my_mysqli_stmt_execute;
1718 } else if (strcmp(fe->fname, "mysqli_stmt_bind_param") == 0) {
1719 old_mysqli_stmt_bind_param = fe->handler;
1720 fe->handler = my_mysqli_stmt_bind_param;
1721 } else if (strcmp(fe->fname, "mysqli_stmt_num_rows") == 0) {
1722 old_mysqli_stmt_num_rows = fe->handler;
1572 1723 } else if (strcmp(fe->fname, "mysqli_stmt_prepare") == 0) { } else if (strcmp(fe->fname, "mysqli_stmt_prepare") == 0) {
1573 1724 old_mysqli_stmt_prepare = fe->handler; old_mysqli_stmt_prepare = fe->handler;
1574 1725 fe->handler = my_mysqli_stmt_prepare; fe->handler = my_mysqli_stmt_prepare;
File agent/process_db.c changed (mode: 100644) (index 8d20f2f..6ec5d24)
... ... void query_send_string(const unsigned char *hash)
277 277 server_enqueue(buf, len); server_enqueue(buf, len);
278 278 } }
279 279
280
281 static char *type2name(const unsigned int type)
282 {
283 switch (type) {
284 case NINEDOGS_DB_CONN_START: return "conn-start";
285 case NINEDOGS_DB_CONN_END: return "conn-end";
286 case NINEDOGS_DB_QUERY_START: return "query-start";
287 case NINEDOGS_DB_QUERY_END: return "query-end";
288 case NINEDOGS_DB_FREE_RESULT: return "free_result";
289 }
290
291 return "?";
292 }
293
294 280 void ninedogs_process_db(const char *func, const unsigned int type, void *d) void ninedogs_process_db(const char *func, const unsigned int type, void *d)
295 281 { {
296 282 struct query_node *qn; struct query_node *qn;
 
... ... void ninedogs_process_db(const char *func, const unsigned int type, void *d)
303 289 char *q_copy; char *q_copy;
304 290 unsigned int q_len; unsigned int q_len;
305 291
306 xlog(100, "%s: type=%s\n", __func__, type2name(type));
292 xlog(100, "%s: type=%u\n", __func__, type);
307 293
308 294 switch (type) { switch (type) {
309 295 case NINEDOGS_DB_CONN_START: case NINEDOGS_DB_CONN_START:
 
... ... void ninedogs_process_db(const char *func, const unsigned int type, void *d)
493 479 break; break;
494 480
495 481 case NINEDOGS_DB_EXECUTE_START: case NINEDOGS_DB_EXECUTE_START:
496 my_trace(func, 'c', (struct execute *) d);
482 my_trace(func, 'c', (struct nd_db_execute *) d);
497 483 break; break;
498 484
499 485 case NINEDOGS_DB_EXECUTE_END: case NINEDOGS_DB_EXECUTE_END:
500 my_trace(func, 'r', (struct execute *) d);
486 my_trace(func, 'r', (struct nd_db_execute *) d);
501 487 break; break;
502 488
503 489 case NINEDOGS_DB_AUTOCOMMIT_START: case NINEDOGS_DB_AUTOCOMMIT_START:
 
... ... void ninedogs_process_db(const char *func, const unsigned int type, void *d)
508 494 my_trace(func, 'r', (struct db_autocommit *) d); my_trace(func, 'r', (struct db_autocommit *) d);
509 495 break; break;
510 496
497 case NINEDOGS_DB_BIND_PARAM_START:
498 my_trace(func, 'c', (struct nd_db_bind *) d);
499 break;
500
501 case NINEDOGS_DB_BIND_PARAM_END:
502 my_trace(func, 'r', (struct nd_db_bind *) d);
503 break;
504
511 505 case NINEDOGS_DB_FREE_RESULT: case NINEDOGS_DB_FREE_RESULT:
512 506 struct free_result *fr = (struct free_result *) d; struct free_result *fr = (struct free_result *) d;
513 507
File agent/process_db.h changed (mode: 100644) (index 05e0db3..dce5b00)
... ... struct conn
16 16
17 17 #define ND_PARAMS_MAX 100 #define ND_PARAMS_MAX 100
18 18
19 #define ND_PARAMS_TYPE_NULL 0
19 20 #define ND_PARAMS_TYPE_LONG 1 #define ND_PARAMS_TYPE_LONG 1
20 21 #define ND_PARAMS_TYPE_DOUBLE 2 #define ND_PARAMS_TYPE_DOUBLE 2
21 22 #define ND_PARAMS_TYPE_STRING 3 #define ND_PARAMS_TYPE_STRING 3
 
... ... struct prepare
78 79 void *stmt; void *stmt;
79 80 }; };
80 81
81 struct execute
82 struct nd_db_execute
82 83 { {
83 84 void *stmt; void *stmt;
84 85 struct params_array params; // this is used in process_db struct params_array params; // this is used in process_db
85 86 char type; char type;
86 87 char ret; char ret;
87 88 char pad1[6]; char pad1[6];
89 unsigned long num, aff;
88 90 }; };
89 91
90 92 struct db_autocommit struct db_autocommit
 
... ... struct db_autocommit
96 98 char pad1[5]; char pad1[5];
97 99 }; };
98 100
101 struct nd_db_bind
102 {
103 void *stmt;
104 char type;
105 char ret;
106 char pad[4];
107 unsigned short types_len;
108 char *types;
109 };
110
111
99 112 void query_send_string(const unsigned char *hash); void query_send_string(const unsigned char *hash);
100 113
101 114 void ninedogs_process_db(const char *func, const unsigned int type, void *d); void ninedogs_process_db(const char *func, const unsigned int type, void *d);
File common/ids.h changed (mode: 100644) (index 468841d..1e80c52)
... ... enum
57 57 NINEDOGS_DB_EXECUTE_END, NINEDOGS_DB_EXECUTE_END,
58 58 NINEDOGS_DB_AUTOCOMMIT_START, NINEDOGS_DB_AUTOCOMMIT_START,
59 59 NINEDOGS_DB_AUTOCOMMIT_END, NINEDOGS_DB_AUTOCOMMIT_END,
60 NINEDOGS_DB_BIND_PARAM_START,
61 NINEDOGS_DB_BIND_PARAM_END,
60 62 NINEDOGS_DB_MAX // this must be last NINEDOGS_DB_MAX // this must be last
61 63 }; };
62 64
File debian/control changed (mode: 100644) (index 5aa03fd..73a16e2)
... ... Source: ninedogs
2 2 Maintainer: Catalin(ux) M. BOIE <catab@embedromix.ro> Maintainer: Catalin(ux) M. BOIE <catab@embedromix.ro>
3 3 Section: misc Section: misc
4 4 Priority: optional Priority: optional
5 Build-Depends: debhelper (>= 9), libgnutls28-dev, json-c-dev, libcap-dev, catalinux+Conn
5 Build-Depends: debhelper (>= 9), libgnutls28-dev, json-c-dev, libcap-dev, texlive-latex-base, catalinux+Conn
6 6 Standards-Version: 3.9.6 Standards-Version: 3.9.6
7 7 Homepage: https://rocketgit.com/user/catalinux/ninedogs Homepage: https://rocketgit.com/user/catalinux/ninedogs
8 8 Vcs-Git: git://rocketgit.com/user/catalinux/ninedogs Vcs-Git: git://rocketgit.com/user/catalinux/ninedogs
File docs/Makefile changed (mode: 100644) (index 0813d5d..ad88c82)
1 all: pre1.pdf
1 PDFs := pre1.pdf
2
3 all: $(PDFs)
4
5 compile: $(PDFs)
2 6
3 7 pre1.pdf: pre1.tex pre1.pdf: pre1.tex
4 pdflatex $<
8 pdflatex $< && pdflatex $<
5 9
File docs/pre1.tex changed (mode: 100644) (index 8207e00..19fc9fe)
9 9
10 10 \title{ninedogs project introduction} \title{ninedogs project introduction}
11 11 \subtitle{ninedogs workshop for Devs and DevOps (tracing)} \subtitle{ninedogs workshop for Devs and DevOps (tracing)}
12 \author{Catalin(ux) M. BOIE}
12 \author{Catalin(ux) M. BOIE - ninedogs@embedromix.ro}
13 13 \date{2022-11-09} \date{2022-11-09}
14 14 %\titlegraphic{\includegraphics[width=2.5cm]{ninedogs.svg}} %\titlegraphic{\includegraphics[width=2.5cm]{ninedogs.svg}}
15 15
 
34 34 \item A set of tools helping the Developers, database/system admins and DevOps \item A set of tools helping the Developers, database/system admins and DevOps
35 35 to get more information from the running processes. to get more information from the running processes.
36 36 \item A client/server application streaming tracing information to the server \item A client/server application streaming tracing information to the server
37 for later analysis.
37 for later analysis (future).
38 38 \item A log collection tool (future). \item A log collection tool (future).
39 39 \item An alerting tool for certificate imminent expiration and security issues alerting. \item An alerting tool for certificate imminent expiration and security issues alerting.
40 \item A tool for live patching of applications (Log4J etc.).
40 \item A tool for live patching of applications (log4j etc.) (future).
41 \item License is AGPL, the most developer and user friendly possible.
41 42 \end{itemize} \end{itemize}
42 43 \end{block} \end{block}
43 44 \end{frame} \end{frame}
 
46 47 \begin{block}{How ninedogs is working?} \begin{block}{How ninedogs is working?}
47 48 \begin{itemize} \begin{itemize}
48 49 \item It uses LD\_PRELOAD mechanism to hook all interesting shared libraries calls. \item It uses LD\_PRELOAD mechanism to hook all interesting shared libraries calls.
49 \item Examples of hooked funtions (not syscalls! it does not use ptrace): recv, send, open,
50 \item Examples of hooked functions (not syscalls! it does not use ptrace): recv, send, open,
50 51 mysqli\_fetch\_array, pg\_pconnect, sqlite3\_open\_v2, syslog etc. mysqli\_fetch\_array, pg\_pconnect, sqlite3\_open\_v2, syslog etc.
51 52 \item Many more will come in each release. \item Many more will come in each release.
52 53 \end{itemize} \end{itemize}
 
65 66 \end{block} \end{block}
66 67 \end{frame} \end{frame}
67 68
68
69 \subsection{Preparations for using ninedogs tracing}
70
71 69 \begin{frame} \begin{frame}
72 \begin{block}{Installation}
70 \begin{block}{What is the performance impact of ninedogs tracing}
73 71 \begin{itemize} \begin{itemize}
74 \item With the help of https://rocketgit.com, we build ninedogs for a lot of
75 distributions and architectures.
76 Check \href{https://rocketgit.com/op/pkg_repos}{https://rocketgit.com/op/pkg\_repos}
77 to see if your distro/arch is supported. Ask if not there.
78 \item ninedogs can be installed both in a normal Linux distribution or in a container.
72 \item It uses shared memory as a ring buffer to pass information to the tracer.
73 \item The biggest cost is copying from memory to memory (negligible).
74 \item It does not block if the ring is full.
75 \item It uses a small amount of memory compared with other products.
79 76 \end{itemize} \end{itemize}
80 77 \end{block} \end{block}
81 78 \end{frame} \end{frame}
82 79
83 80
81 \section{Installation and basic usage}
82
83 \subsection{Preparations for using ninedogs tracing}
84
85 \begin{frame}{Installation - general info}
86 \begin{itemize}
87 \item With the help of \href{https://rocketgit.com}{RocketGit project},
88 we build ninedogs for multiple distributions and architectures.
89
90 Check \href{https://rocketgit.com/op/pkg_repos}{https://rocketgit.com/op/pkg\_repos}
91 to see if your distro/arch is supported. Ask if is not there.
92 \item ninedogs can be installed both in a normal Linux distribution or in a container.
93 \end{itemize}
94 \end{frame}
95
96 \begin{frame}[fragile]{VMs/baremetal installation and usage}
97 \begin{block}{Fedora/RedHat/Alma/Rocky}
98 \tiny
99 \begin{verbatim}
100 # Installing RocketGit repository (so you will get updates automatically)
101 dnf install https://rocketgit.com/op/pkgrepo/main/global/testing/fedora/37/x86_64/os/rocketgit-global-testing-1.1-1.noarch.rpm
102 # Installing package
103 dnf install catalinux+ninedogs
104 \end{verbatim}
105 \end{block}
106 \begin{block}{Usage in a systemd service file}
107 \small
108 \begin{verbatim}
109 TODO
110 \end{verbatim}
111 \end{block}
112 \end{frame}
113
114 \begin{frame}[fragile]{Container installation and usage}
115 \begin{block}{Dockerfile}
116 \tiny
117 \begin{verbatim}
118 FROM fedora:37
119 [...]
120 RUN dnf -y --setopt=tsflags=nodocs install \
121 https://rocketgit.com/op/pkgrepo/main/global/testing/fedora/37/x86_64/os/rocketgit-global-testing-1.1-1.noarch.rpm \
122 && dnf -y --setopt=tsflags=nodocs install catalinux+ninedogs \
123 && dnf -y clean all
124 \end{verbatim}
125 \end{block}
126 \begin{block}{In the start script...}
127 \small
128 \begin{verbatim}
129 LD_PRELOAD=ninedogs.so path_to_your_program
130 \end{verbatim}
131 \end{block}
132 \begin{block}{... or set at run-time}
133 \small
134 \begin{verbatim}
135 podman run -e LD_PRELOAD=ninedogs.so image command
136 docker run -e LD_PRELOAD=ninedogs.so image command
137 \end{verbatim}
138 \end{block}
139 \end{frame}
140
141
142
84 143 \section{Demo} \section{Demo}
85 144
86 145 \subsection{Real life examples} \subsection{Real life examples}
87 146
88
89 147 \begin{frame}[fragile]{MySQL connection} \begin{frame}[fragile]{MySQL connection}
148 \begin{block}{PHP code}
149 \tiny
150 \begin{verbatim}
151 $db = mysqli_init();
152 mysqli_real_connect($db, 'h1', 'ninedogs', 'pass', 'ninedogs', 3306, FALSE, MYSQLI_CLIENT_COMPRESS);
153 \end{verbatim}
154 \end{block}
90 155 \begin{block}{strace} \begin{block}{strace}
91 156 \tiny \tiny
92 157 \begin{verbatim} \begin{verbatim}
 
... ... fcntl(5, F_GETFL) = 0x2 (flags O_RDWR)
95 160 fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK) = 0 fcntl(5, F_SETFL, O_RDWR|O_NONBLOCK) = 0
96 161 connect(5, {sa_family=AF_INET, sin_port=htons(3306), sin_addr=inet_addr("x.x.x.x")},16) connect(5, {sa_family=AF_INET, sin_port=htons(3306), sin_addr=inet_addr("x.x.x.x")},16)
97 162 = -1 EINPROGRESS (Operation now in progress) = -1 EINPROGRESS (Operation now in progress)
98 poll([{fd=5, events=POLLIN\|POLLOUT\|POLLERR\|POLLHUP}], 1, 60000) = 1 ([{fd=5, revents=POLLOUT}])
163 poll([{fd=5, events=POLLIN|POLLOUT|POLLERR|POLLHUP}], 1, 60000) = 1 ([{fd=5, revents=POLLOUT}])
99 164 getsockopt(5, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 getsockopt(5, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
100 fcntl\(5, F_SETFL, O_RDWR\) = 0
165 fcntl(5, F_SETFL, O_RDWR) = 0
101 166 setsockopt(5, SOL_TCP, TCP_NODELAY, [1], 4) = 0 setsockopt(5, SOL_TCP, TCP_NODELAY, [1], 4) = 0
102 167 setsockopt(5, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0 setsockopt(5, SOL_SOCKET, SO_KEEPALIVE, [1], 4) = 0
103 168 poll([{fd=5, events=POLLIN|POLLERR|POLLHUP}], 1, 86400000) = 1 ([{fd=5, revents=POLLIN}]) poll([{fd=5, events=POLLIN|POLLERR|POLLHUP}], 1, 86400000) = 1 ([{fd=5, revents=POLLIN}])
104 169 recvfrom(5, "Y\0\0\0\n5.5.5-10.5.16-MariaDB...", 32768, MSG_DONTWAIT, NULL, NULL) = 93 recvfrom(5, "Y\0\0\0\n5.5.5-10.5.16-MariaDB...", 32768, MSG_DONTWAIT, NULL, NULL) = 93
105 170 sendto(5, "\203\0\0\1\315...", 135, MSG_DONTWAIT, NULL, 0) = 135 sendto(5, "\203\0\0\1\315...", 135, MSG_DONTWAIT, NULL, 0) = 135
106 171 poll([{fd=5, events=POLLIN|POLLERR|POLLHUP}], 1, 86400000) = 1 ([{fd=5, revents=POLLIN}]) poll([{fd=5, events=POLLIN|POLLERR|POLLHUP}], 1, 86400000) = 1 ([{fd=5, revents=POLLIN}])
107 recvfrom(5, "\7\0\0\2\0\0\0\2\0\0\0", 32768, MSG_DONTWAIT, NULL, NULL) = 11}
172 recvfrom(5, "\7\0\0\2\0\0\0\2\0\0\0", 32768, MSG_DONTWAIT, NULL, NULL) = 11
173 \end{verbatim}
174 \end{block}
175 \begin{block}{nd-trace}
176 \tiny
177 \begin{verbatim}
178 mysqli_real_connect(link=0x7ffba947f190, 'host=h1 user=ninedogs port=3306 db=ninedogs socket=',
179 flags='0x20|COMPRESS')
180 [strace like output (connect/poll/recvfrom/sendto etc.) omitted]
181 mysqli_real_connect(link=0x7ffba947f190, 'host=h1 user=ninedogs port=3306 db=ninedogs socket=',
182 flags='0x20|COMPRESS') = ok
108 183 \end{verbatim} \end{verbatim}
109 184 \end{block} \end{block}
185 \end{frame}
186
110 187
188 \begin{frame}[fragile]{PostgreSQL query}
189 \begin{block}{PHP code}
190 \tiny
191 \begin{verbatim}
192 $sql = 'SELECT id FROM n1 WHERE id = $1 OR id = $2 OR d = $3 OR a1 = $4 OR a1 = $5';
193 $params = array(3, '4', 1.2, NULL, FALSE);
194 $res = pg_query_params($db, $sql, $params);
195 \end{verbatim}
196 \end{block}
197 \begin{block}{strace}
198 \tiny
199 \begin{verbatim}
200 sendto(10, "P\0\0\0R\0SELECT id FROM n1 WHERE id = $1 OR id = $2 OR d = $3 OR a1 = $4 OR a1 = $5
201 \0\0\0B\0\0\0'\0\0\0\0\0\5\0\0\0\0013\0\0\0\0014\0\0\0\0031.2\377\377\377\377\0\0\0\0\0
202 \1\0\0D\0\0\0\6P\0E\0\0\0\t\0\0\0\0\0S\0\0\0\4", 145, MSG_NOSIGNAL, NULL, 0) = 145
203 \end{verbatim}
204 \end{block}
205 \begin{block}{nd-trace}
206 \tiny
207 \begin{verbatim}
208 pg_query_params(h=0x7fb55be6a4d0, 'SELECT id FROM n1 WHERE id = $1 OR id = $2 OR d = $3 OR a1 = $4 OR a1 = $5')
209 {1:long:3, 2:str:'4', 3:double:1.200000, 4:NULL, 5:str:'false'}
210 pg_query_params(h=0x7fb55be6a4d0, 'SELECT id FROM n1 WHERE id = $1 OR id = $2 OR d = $3 OR a1 = $4 OR a1 = $5')
211 = 0x7fb55be03198 [2 rows, 2 aff]
212 \end{verbatim}
213 \end{block}
214 \end{frame}
215
216
217 \begin{frame}[fragile]{MySQL query}
218 \begin{block}{PHP code}
219 \tiny
220 \begin{verbatim}
221 $stmt = mysqli_stmt_init($db);
222 $sql = 'SELECT id, a1 FROM n1 WHERE id = ? OR id = ? OR d = ? OR a1 = ? OR a1 = ?';
223 mysqli_stmt_prepare($stmt, $sql);
224 mysqli_stmt_execute($stmt, array('1', '2', '3', '4', 5));
225 \end{verbatim}
226 \end{block}
227 \begin{block}{strace}
228 \tiny
229 \begin{verbatim}
230 sendto(5, "J\0\0\0\26SELECT id, a1 FROM n1 WHERE id = ? OR id = ? OR d = ? OR a1 = ? OR a1 = ?",
231 78, MSG_DONTWAIT, NULL, 0) = 78
232 sendto(5, " \0\0\0\27\4\0\0\0\0\1\0\0\0\0\1\375\0\375\0\375\0\375\0\375\0\0011\0012\0013\0014\0015",
233 36, MSG_DONTWAIT, NULL, 0) = 36
234 \end{verbatim}
235 \end{block}
111 236 \begin{block}{nd-trace} \begin{block}{nd-trace}
112 237 \tiny \tiny
113 238 \begin{verbatim} \begin{verbatim}
114 mysqli_real_connect(link=0x7fc52127f010, 'host=h1 user=ninedogs port=3306 db=ninedogs socket=',
115 flags='0x40|SSL_DONT_VERIFY_SERVER_CERT')
116 [strace like output (connect/poll/recvfrom/sendto etc.) ommited]
117 mysqli_real_connect(link=0x7fc52127f010, 'host=h1 user=ninedogs port=3306 db=ninedogs socket=',
118 flags='0x40|SSL_DONT_VERIFY_SERVER_CERT') = ok
239 mysqli_stmt_prepare(stmt=0x7fc52127c390, 'SELECT id, a1 FROM n1 WHERE id = ? OR id = ? OR d = ? OR a1 = ? OR a1 = ?')
240 mysqli_stmt_prepare(stmt=0x7fc52127c390, 'SELECT id, a1 FROM n1 WHERE id = ? OR id = ? OR d = ? OR a1 = ? OR a1 = ?') = ok
241 mysqli_stmt_execute(stmt=0x7fc52127c390, {1:str:'1', 2:str:'2', 3:str:'3', 4:str:'4', 5:long:5})
242 mysqli_stmt_execute(stmt=0x7fc52127c390) = ok
119 243 \end{verbatim} \end{verbatim}
120 244 \end{block} \end{block}
121 245 \end{frame} \end{frame}
122 246
123 247
124 248 \begin{frame}[fragile]{sqlite3} \begin{frame}[fragile]{sqlite3}
249 \begin{block}{Python code}
250 \tiny
251 \begin{verbatim}
252 db = sqlite3.connect('/bla/sqlite1.db')
253 cursor = db.cursor()
254 query = 'INSERT INTO test1 VALUES (:id, :val);'
255 cursor.execute(query, { "id": 1, "val": "first_value"})
256 \end{verbatim}
257 \end{block}
125 258 \begin{block}{strace} \begin{block}{strace}
126 259 \tiny \tiny
127 260 \begin{verbatim} \begin{verbatim}
128 openat(AT_FDCWD, "/date/sync/no-crypt/sync1/Dev/ninedogs/test/python/sqlite1.db",
129 O_RDWR|O_CREAT|O_NOFOLLOW|O_CLOEXEC, 0644) = 3
261 openat(AT_FDCWD, "/bla/sqlite1.db", O_RDWR|O_CREAT|O_NOFOLLOW|O_CLOEXEC, 0644) = 3
130 262 pread64(3, "SQLite format 3...", 100, 0) = 100 pread64(3, "SQLite format 3...", 100, 0) = 100
131 263 fcntl(3, F_SETLK, {l_type=F_RDLCK, l_whence=SEEK_SET, l_start=1073741824, l_len=1}) = 0 fcntl(3, F_SETLK, {l_type=F_RDLCK, l_whence=SEEK_SET, l_start=1073741824, l_len=1}) = 0
132 264 [lots of pread64/pwrite64/fcntl removed] [lots of pread64/pwrite64/fcntl removed]
133 265 pwrite64(3, "...\0\16\1\3\t#first_value", 4096, 4096) = 4096 pwrite64(3, "...\0\16\1\3\t#first_value", 4096, 4096) = 4096
134 266 \end{verbatim} \end{verbatim}
135 267 \end{block} \end{block}
136
137 268 \begin{block}{nd-trace} \begin{block}{nd-trace}
138 269 \tiny \tiny
139 270 \begin{verbatim} \begin{verbatim}
140 sqlite3_open_v2('sqlite1.db', 0x6|READWRITE|CREATE, '')
141 sqlite3_open_v2('sqlite1.db', 0x55c13dfba5a8, 0x6|READWRITE|CREATE, '') = OK
271 sqlite3_open_v2('/bla/sqlite1.db', 0x6|READWRITE|CREATE, '')
272 sqlite3_open_v2('/bla/sqlite1.db', 0x55c13dfba5a8, 0x6|READWRITE|CREATE, '') = ok
142 273 sqlite3_prepare_v2(0x55794910b5a8, 'INSERT INTO test1 VALUES (:id, :val);', -1, stmt, tail) sqlite3_prepare_v2(0x55794910b5a8, 'INSERT INTO test1 VALUES (:id, :val);', -1, stmt, tail)
143 sqlite3_prepare_v2(0x55794910b5a8, 'INSERT INTO test1 VALUES (:id, :val);', -1, 0x55794918e388, tail) = OK
144 sqlite3_bind_int64(stmt=0x5594c1d78388, index=1, value=1) = OK
145 sqlite3_bind_text(stmt=0x55d53848e388, index=2, 'first_value') = OK
274 sqlite3_prepare_v2(0x55794910b5a8, 'INSERT INTO test1 VALUES (:id, :val);', -1, 0x55794918e388, tail) = ok
275 sqlite3_bind_int64(stmt=0x5594c1d78388, index=1, value=1) = ok
276 sqlite3_bind_text(stmt=0x55d53848e388, index=2, 'first_value') = ok
146 277 sqlite3_step(0x5594c1d78388) sqlite3_step(0x5594c1d78388)
147 sqlite3_step(0x5594c1d78388) = DONE
148 sqlite3_finalize(0x5594c1d78388) = OK
278 sqlite3_step(0x5594c1d78388) = DONE
279 sqlite3_finalize(0x5594c1d78388) = ok
149 280 \end{verbatim} \end{verbatim}
150 281 \end{block} \end{block}
151 282 \end{frame} \end{frame}
152 283
153
154 284 \begin{frame}[fragile]{Hostname resolving} \begin{frame}[fragile]{Hostname resolving}
155 285 \begin{block}{strace} \begin{block}{strace}
156 286 \tiny \tiny
 
... ... epoll_ctl(13, EPOLL_CTL_DEL, 20, 0x7f43aa4aaa04) = 0
175 305 close(20) close(20)
176 306 \end{verbatim} \end{verbatim}
177 307 \end{block} \end{block}
178
179 308 \begin{block}{nd-trace} \begin{block}{nd-trace}
180 309 \tiny \tiny
181 310 \begin{verbatim} \begin{verbatim}
 
... ... gethostbyname_r('bla.com.com.com')
186 315 \end{frame} \end{frame}
187 316
188 317
189 \section{Other interesting things}
318 \subsection{Other interesting things}
190 319
191 320 \begin{frame}[fragile]{Segmentation fault} \begin{frame}[fragile]{Segmentation fault}
192 321 \begin{block}{strace} \begin{block}{strace}
 
... ... gethostbyname_r('bla.com.com.com')
197 326 Segmentation fault (core dumped) Segmentation fault (core dumped)
198 327 \end{verbatim} \end{verbatim}
199 328 \end{block} \end{block}
200
201 329 \begin{block}{nd-trace} \begin{block}{nd-trace}
202 330 \tiny \tiny
203 331 \begin{verbatim} \begin{verbatim}
 
... ... Segmentation fault (core dumped)
212 340 \end{frame} \end{frame}
213 341
214 342
215 \begin{frame}[fragile]{bla - no tiny}
216 \begin{block}{}
217 \tiny
218 \begin{verbatim}
219 \end{verbatim}
220 \end{block}
343 \section{Misc}
221 344
222 \begin{block}{ - nd-trace}
223 \tiny
224 \begin{verbatim}
225 text
226 \end{verbatim}
227 \end{block}
345 \subsection{What is coming next?}
346
347 \begin{frame}{What is coming next?}
348 \begin{itemize}
349 \item More functions interception.
350 \item Send logs to the server (intercept any open of filenames containing '.log' or '/logs?/').
351 \item Adding a cron to report used certificates close to expiration date.
352 \item nd-trace: report statistics (number of calls and average time spent per function).
353 \end{itemize}
354 \end{frame}
355
356 \begin{frame}
357 \center
358 Thank you!
359
360 Contact: ninedogs@embedromix.ro
361
362 Download/history/artifacts: \href{https://rocketgit.com/user/catalinux/ninedogs}{https://rocketgit.com/user/catalinux/ninedogs}
363
364 We need sponsors, please contact us if you want to become one.
228 365 \end{frame} \end{frame}
229 366
230 367
File docs/pre1.txt changed (mode: 100644) (index df692d4..3a09c93)
1 1 Ideas for the first presentation Ideas for the first presentation
2 2
3 - Who is the target of the prezentation.
3 - Who is the target of the presentation.
4 4 - Why? - Why?
5 5 - Difference between strace and nd-trace - Difference between strace and nd-trace
6 6 - Why strace cannot be used in cloud in containers - Why strace cannot be used in cloud in containers
7 7 - Talk about high-level decoding - Talk about high-level decoding
8 8 - Show some examples - Show some examples
9 9 - Performance impact - Performance impact
10 - Sponsors?
11 - License!
10 12 - -
File docs/spell_check.sh added (mode: 100755) (index 0000000..6a4e415)
1 #!/bin/bash
2
3 cdir=${PWD}
4
5 find . \
6 -name '*.tex' \
7 -o -name '*.txt' \
8 | while read f; do
9 aspell --dont-backup check "${f}" </dev/tty &>/dev/tty
10 done
File ninedogs.spec changed (mode: 100644) (index 154b5eb..80213d4)
... ... Conflicts: ninedogs
15 15
16 16 Requires: json-c, gnutls, libcap, catalinux+Conn, nginx-filesystem Requires: json-c, gnutls, libcap, catalinux+Conn, nginx-filesystem
17 17
18 BuildRequires: systemd-rpm-macros, json-c-devel, gnutls-devel, libcap-devel, catalinux+Conn
18 BuildRequires: systemd-rpm-macros, json-c-devel, gnutls-devel, libcap-devel, texlive-latex, catalinux+Conn
19 19
20 20 %description %description
21 21 Light and fast APM Light and fast APM
File rocketgit/artifacts added (mode: 100644) (index 0000000..b219d7f)
1 docs/
2 regex = \.pdf$
3 map = docs/
4 content_type = application/pdf
5
File test/php-container/Dockerfile changed (mode: 100644) (index c950697..b65621b)
1 1 FROM fedora:37 FROM fedora:37
2 2 MAINTAINER Catalin(ux) M. BOIE <catab-docker@embedromix.ro> MAINTAINER Catalin(ux) M. BOIE <catab-docker@embedromix.ro>
3 3
4 RUN echo 1
4 RUN echo 2
5 5 RUN dnf -y --setopt=tsflags=nodocs upgrade --best --allowerasing RUN dnf -y --setopt=tsflags=nodocs upgrade --best --allowerasing
6 6 RUN dnf -y --setopt=tsflags=nodocs install \ RUN dnf -y --setopt=tsflags=nodocs install \
7 7 https://rocketgit.com/op/pkgrepo/main/global/testing/fedora/37/x86_64/os/rocketgit-global-testing-1.1-1.noarch.rpm https://rocketgit.com/op/pkgrepo/main/global/testing/fedora/37/x86_64/os/rocketgit-global-testing-1.1-1.noarch.rpm
File test/php-container/exec.sh changed (mode: 100755) (index 7a4f933..a41ea9d)
8 8 #strace -s200 -tt -f -q -o podman.strace \ #strace -s200 -tt -f -q -o podman.strace \
9 9 podman run -ti --rm \ podman run -ti --rm \
10 10 \ \
11 -e LD_PRELOAD=ninedogs.so \
11 12 \ \
12 13 -v ${PWD}/1.php:/1.php \ -v ${PWD}/1.php:/1.php \
13 14 -v ${PWD}/1:/1 \ -v ${PWD}/1:/1 \
File test/php-mysql/1.php changed (mode: 100644) (index 21e5b0c..cfde800)
... ... for ($i = 0; $i < 4; $i++) {
22 22 FALSE, MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT); FALSE, MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT);
23 23 } }
24 24
25 echo 'Connecting with compress flags...' . "\n";
26 mysqli_real_connect($db, 'r1', 'ninedogs', 'pass', 'ninedogs', 3306, FALSE, MYSQLI_CLIENT_COMPRESS);
27
25 28
26 29 echo 'Setting charset...' . "\n"; echo 'Setting charset...' . "\n";
27 30 mysqli_set_charset($db, 'utf8mb4'); mysqli_set_charset($db, 'utf8mb4');
 
... ... mysqli_stmt_prepare($stmt, $sql);
91 94 echo 'Calling mysqli_stmt_bind_param...' . "\n"; echo 'Calling mysqli_stmt_bind_param...' . "\n";
92 95 mysqli_stmt_bind_param($stmt, 'iidss', $a, $b, $c, $d, $e); mysqli_stmt_bind_param($stmt, 'iidss', $a, $b, $c, $d, $e);
93 96 $a = 1; $b = $a + 1; $c = 8.3; $d = 'bla'; $e = 'bla2'; $a = 1; $b = $a + 1; $c = 8.3; $d = 'bla'; $e = 'bla2';
94 echo 'Calling mysqli_stmt_execute 1...' . "\n";
97 echo 'Calling mysqli_stmt_execute 1 (without array)...' . "\n";
95 98 mysqli_stmt_execute($stmt); mysqli_stmt_execute($stmt);
96 echo 'Calling mysqli_stmt_execute 2...' . "\n";
97 mysqli_stmt_execute($stmt, array('1', '2', '3', '4', '5'));
99 echo 'Calling mysqli_stmt_execute 2 (with array)...' . "\n";
100 mysqli_stmt_execute($stmt, array('1', '2', '3', '4', 5));
98 101 echo 'Calling mysqli_stmt_get_result...' . "\n"; echo 'Calling mysqli_stmt_get_result...' . "\n";
99 102 $res = mysqli_stmt_get_result($stmt); $res = mysqli_stmt_get_result($stmt);
100 103 echo 'Calling native mysqli_num_rows:' . "\n"; echo 'Calling native mysqli_num_rows:' . "\n";
File test/php-mysql/stmt_bind_param.php added (mode: 100644) (index 0000000..4045b38)
1 <?php
2 error_reporting(E_ALL);
3
4 echo 'Connecting...' . "\n";
5 $db = mysqli_init();
6 mysqli_real_connect($db, 'r1', 'ninedogs', 'pass', 'ninedogs', 3306,
7 FALSE, MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT);
8
9 echo 'Setting charset...' . "\n";
10 mysqli_set_charset($db, 'utf8mb4');
11
12 echo 'Setting autocommit to true...' . "\n";
13 mysqli_autocommit($db, TRUE);
14
15 echo 'Querying with parameters (mysqli_stmt_prepare)...' . "\n";
16 $sql = 'SELECT id, a1 FROM n1 WHERE id = ? OR id = ? OR d = ? OR a1 = ? OR a1 = ?';
17
18 echo 'Calling mysqli_stmt_init...' . "\n";
19 $stmt = mysqli_stmt_init($db);
20
21 echo 'Calling mysqli_stmt_prepare...' . "\n";
22 mysqli_stmt_prepare($stmt, $sql);
23
24 echo 'Calling mysqli_stmt_bind_param...' . "\n";
25 mysqli_stmt_bind_param($stmt, 'iidss', $a, $b, $c, $d, $e);
26
27 echo 'Calling mysqli_stmt_execute 1...' . "\n";
28 $a = 1; $b = $a + 1; $c = 8.3; $d = 'bla'; $e = 'bla2';
29 mysqli_stmt_execute($stmt);
30
31 echo 'Calling mysqli_stmt_execute 2...' . "\n";
32 $a = 2; $b = $a + 1; $c = 8.4; $d = 'bla2'; $e = 'bla3';
33 mysqli_stmt_execute($stmt);
34
35 echo 'Done!' . "\n";
36
File test/php-mysql/stmt_bind_param.run copied from file test/python/redis1.run (similarity 55%) (mode: 100755) (index c00c847..bca3d2f)
... ... export NINEDOGS_VERBOSE=141
9 9 export NINEDOGS_SYNC_FLUSH=1 export NINEDOGS_SYNC_FLUSH=1
10 10
11 11 #export LD_DEBUG=all #export LD_DEBUG=all
12 export LD_DEBUG_OUTPUT=redis1.ld.txt
12 export LD_DEBUG_OUTPUT=stmt_bind_param.ld.txt
13 13
14 14 export DEBUGINFOD_URLS= export DEBUGINFOD_URLS=
15 15
16 #ltrace -s200 -f -tt -S -o stmt_bind_param.ltrace \
16 17 #valgrind -v --trace-children=yes \ #valgrind -v --trace-children=yes \
17 #strace -tt -f -s2000 -o 1.strace \
18 ltrace -s200 -f -tt -S -o redis1.ltrace \
19 python redis1.py 2>&1 | LD_PRELOAD= tee redis1.out
20
21 exit 0
22
23 python redis1.py &
24 LD_PRELOAD= ../../trace/nd-trace -o redis1.nd -p ${!}
18 #strace -tt -f -s2000 -o stmt_bind_param.strace \
19 php stmt_bind_param.php &>stmt_bind_param.out &
20 LD_PRELOAD= LD_DEBUG= ../../trace/nd-trace -o stmt_bind_param.nd -p ${!}
25 21
File test/php-pg/1.php changed (mode: 100644) (index b714e25..12171cb)
1 1 <?php <?php
2 2 error_reporting(E_ALL); error_reporting(E_ALL);
3 3
4 sleep(1);
5
4 6 //echo 'Setting some tags...' . "\n"; //echo 'Setting some tags...' . "\n";
5 7 //@stat('/ninedogs/tag/tag1,tag2,tag3'); //@stat('/ninedogs/tag/tag1,tag2,tag3');
6 8 //@stat('/ninedogs/tag/tag1,tag2,tag3'); //@stat('/ninedogs/tag/tag1,tag2,tag3');
File test/php-pg/1.run changed (mode: 100755) (index ebe5353..0d2f00a)
... ... export LD_PRELOAD=../../agent/ninedogs.so
5 5 export NINEDOGS_SERVER_HOSTNAME=rg.embedromix.ro export NINEDOGS_SERVER_HOSTNAME=rg.embedromix.ro
6 6 export NINEDOGS_SERVER_PORT=36000 export NINEDOGS_SERVER_PORT=36000
7 7 export NINEDOGS_ID=ba446a981b387e831db3f6a730c55556 export NINEDOGS_ID=ba446a981b387e831db3f6a730c55556
8 export NINEDOGS_VERBOSE=41
8 export NINEDOGS_VERBOSE=241
9 9 export NINEDOGS_SYNC_FLUSH=1 export NINEDOGS_SYNC_FLUSH=1
10 10
11 11 #export LD_DEBUG=all #export LD_DEBUG=all
File test/trace/syslog1.c changed (mode: 100644) (index f130731..a4aeddb)
2 2
3 3 int main(int argc, char *argv[]) int main(int argc, char *argv[])
4 4 { {
5 sleep(2);
5 sleep(1);
6 6 syslog(1, "aaa %d", 1); syslog(1, "aaa %d", 1);
7 7 return 0; return 0;
8 8 } }
File test/trace/syslog1.run changed (mode: 100755) (index d8a59ec..0587a2f)
... ... export LD_DEBUG_OUTPUT=syslog1.ld.txt
16 16 export DEBUGINFOD_URLS= export DEBUGINFOD_URLS=
17 17
18 18 LD_PRELOAD=../../agent/ninedogs.so ./syslog1 &> syslog1.out & LD_PRELOAD=../../agent/ninedogs.so ./syslog1 &> syslog1.out &
19 echo "Child pid is ${!}"
20 sleep .4
21 ../../trace/nd-trace -o syslog1.trace.out -p ${!}
19 ../../trace/nd-trace -o syslog1.nd -p ${!}
22 20
File trace/nd-trace.c changed (mode: 100644) (index d07ee21..6843c12)
... ... static int decode_sqlite3_ret(char *out, unsigned out_size,
608 608 unsigned int ret = decode32(d, i); unsigned int ret = decode32(d, i);
609 609
610 610 switch (ret) { switch (ret) {
611 case 0: snprintf(out, out_size, "OK"); break;
611 case 0: snprintf(out, out_size, "ok"); break;
612 612 case 1: snprintf(out, out_size, "ERROR"); break; case 1: snprintf(out, out_size, "ERROR"); break;
613 613 case 2: snprintf(out, out_size, "INTERNAL"); break; case 2: snprintf(out, out_size, "INTERNAL"); break;
614 614 case 3: snprintf(out, out_size, "PERM"); break; case 3: snprintf(out, out_size, "PERM"); break;
 
... ... static void decode_query_params(char *out, size_t out_size,
747 747 rest -= 2; rest -= 2;
748 748 } }
749 749
750 char *add = "";
750 char *add = "", do_break = 0;
751 751 for (unsigned short j = 0; j < params_len; j++) { for (unsigned short j = 0; j < params_len; j++) {
752 752 char value[64]; char value[64];
753 753 uint8_t type = decode8(d, i); uint8_t type = decode8(d, i);
754 if (type == 1) { // long
754 if (type == 0) { // NULL
755 snprintf(value, sizeof(value),
756 "%hu:NULL", j + 1);
757 } else if (type == 1) { // long
755 758 snprintf(value, sizeof(value), snprintf(value, sizeof(value),
756 759 "%hu:long:%ld", j + 1, decode64(d, i)); "%hu:long:%ld", j + 1, decode64(d, i));
757 760 } else if (type == 2) { // double } else if (type == 2) { // double
761 double dd;
762 uint64_t u = decode64(d, i);
763 memcpy(&dd, &u, 8);
758 764 snprintf(value, sizeof(value), snprintf(value, sizeof(value),
759 "%hu:double:%f", j + 1, (double) decode64(d, i));
765 "%hu:double:%f", j + 1, dd);
760 766 } else if (type == 3) { // string } else if (type == 3) { // string
761 767 uint16_t len = decode16(d, i); uint16_t len = decode16(d, i);
762 768 char s[len * 4 + 1]; char s[len * 4 + 1];
763 769 bin2hex_ascii(s, d + *i, len); *i = *i + len; bin2hex_ascii(s, d + *i, len); *i = *i + len;
764 770 snprintf(value, sizeof(value), snprintf(value, sizeof(value),
765 771 "%hu:str:'%s'", j + 1, s); "%hu:str:'%s'", j + 1, s);
772 } else {
773 snprintf(value, sizeof(value),
774 "%hu:unk, ...", j + 1);
775 do_break = 1; // we cannot continue
766 776 } }
767 777
768 778 len = 2 + strlen(value); len = 2 + strlen(value);
 
... ... static void decode_query_params(char *out, size_t out_size,
773 783 strcat(out, value); strcat(out, value);
774 784 add = ", "; add = ", ";
775 785 rest -= len; rest -= len;
786
787 if (do_break)
788 break;
776 789 } }
777 790
778 791 strcat(out, "}"); strcat(out, "}");
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1135 1148 bin2hex_ascii(q, d + i, q_len); i += q_len; bin2hex_ascii(q, d + i, q_len); i += q_len;
1136 1149 if (type == 'r') { if (type == 'r') {
1137 1150 uint64_t res = decode64(d, &i); uint64_t res = decode64(d, &i);
1151 uint64_t rows = decode64(d, &i);
1152 uint64_t aff = decode64(d, &i);
1138 1153 if (res == 0) if (res == 0)
1139 1154 snprintf(rest, sizeof(rest), " = nok"); snprintf(rest, sizeof(rest), " = nok");
1140 1155 else if (res == 1) else if (res == 1)
1141 snprintf(rest, sizeof(rest), " = ok");
1156 snprintf(rest, sizeof(rest), " = ok [%lu rows, %ld aff]",
1157 rows, aff);
1142 1158 else else
1143 snprintf(rest, sizeof(rest), " = 0x%lx", res);
1159 snprintf(rest, sizeof(rest),
1160 " = 0x%lx [%lu rows, %ld aff]",
1161 res, rows, aff);
1144 1162 } }
1145 1163 sprintf(line, "(link=0x%lx, '%s')%s", link, q, rest); sprintf(line, "(link=0x%lx, '%s')%s", link, q, rest);
1146 1164 } else if (strcmp(func, "mysqli_real_connect") == 0) { } else if (strcmp(func, "mysqli_real_connect") == 0) {
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1153 1171 if (type == 'r') if (type == 'r')
1154 1172 decode_bool(" = ", rest, sizeof(rest), d, &i); decode_bool(" = ", rest, sizeof(rest), d, &i);
1155 1173 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);
1174 } else if (strcmp(func, "mysqli_stmt_bind_param") == 0) {
1175 //char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump);
1176 uint64_t stmt = decode64(d, &i);
1177 unsigned short types_len = decode16(d, &i);
1178 char types[types_len * 4 + 1];
1179 bin2hex_ascii(types, d + i, types_len); i += types_len;
1180 if (type == 'r')
1181 decode_bool(" = ", rest, sizeof(rest), d, &i);
1182 sprintf(line, "(stmt=0x%lx, types='%s', ...)%s",
1183 stmt, types, rest);
1156 1184 } else if (strcmp(func, "mysqli_stmt_execute") == 0) { } 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);
1185 //char dump[4096]; bin2hex_ascii(dump, d + i, 128); fprintf(out, "DUMP[%s][%c]: %s\n", func, type, dump);
1158 1186 uint64_t stmt = decode64(d, &i); uint64_t stmt = decode64(d, &i);
1159 1187 if (type == 'c') { if (type == 'c') {
1160 1188 decode_query_params(rest, sizeof(rest), d, &i); decode_query_params(rest, sizeof(rest), d, &i);
 
... ... static void decode_func(const uint32_t parent, unsigned char *d)
1162 1190 stmt, rest[0] ? ", " : "", rest); stmt, rest[0] ? ", " : "", rest);
1163 1191 } else if (type == 'r') { } else if (type == 'r') {
1164 1192 uint8_t ret = decode8(d, &i); uint8_t ret = decode8(d, &i);
1165 if (ret == 1)
1166 snprintf(rest, sizeof(rest), " = ok");
1167 else
1193 if (ret == 1) {
1194 uint64_t rows = decode64(d, &i);
1195 uint64_t aff = decode64(d, &i);
1196 snprintf(rest, sizeof(rest),
1197 " = ok [%lu rows, %ld aff]", rows, aff);
1198 } else {
1168 1199 snprintf(rest, sizeof(rest), " = nok"); snprintf(rest, sizeof(rest), " = nok");
1200 }
1169 1201 sprintf(line, "(stmt=0x%lx)%s", stmt, rest); sprintf(line, "(stmt=0x%lx)%s", stmt, rest);
1170 1202 } }
1171 1203 } else if (strcmp(func, "mysqli_stmt_prepare") == 0) { } else if (strcmp(func, "mysqli_stmt_prepare") == 0) {
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/catalinux/ninedogs

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/catalinux/ninedogs

Clone this repository using git:
git clone git://git.rocketgit.com/user/catalinux/ninedogs

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main