From eea9d9dbe84e0c6d9da11a15ca46a83a7a603d9c Mon Sep 17 00:00:00 2001 From: dyjakan Date: Thu, 14 May 2015 23:46:32 +0200 Subject: [PATCH 01/19] dtrace-based memory tracer for OS X --- dtracetool/memtrace.d | 102 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100755 dtracetool/memtrace.d diff --git a/dtracetool/memtrace.d b/dtracetool/memtrace.d new file mode 100755 index 0000000..4a30cb5 --- /dev/null +++ b/dtracetool/memtrace.d @@ -0,0 +1,102 @@ +#!/usr/sbin/dtrace -s + +/* +memtrace.d - DTrace-based memory allocation tracer +Andrzej Dyjak + +Based on ltrace output style. Compatible with villoc [1]. + +$ sudo dtrace ./memtrace.d -p +$ sudo dtrace ./memtrace.d -c + +NOTE: For bigger programs you may stumble upon data drops. This can be mitigated +to a certain degree via DTrace tuning [2] [3]. + +[1] https://github.com/wapiflapi/villoc +[2] https://wikis.oracle.com/display/DTrace/Buffers+and+Buffering +[3] https://wikis.oracle.com/display/DTrace/Options+and+Tunables +*/ + +/* Re-enable to see potential data drops */ +#pragma D option quiet + +#pragma D option destructive +#pragma D option bufsize=256m + +/* +TODO: + o More testing (custom test for each function) + o Customize villoc.py for reallocf() and valloc() + o Do we need all these predicates? +*/ + +pid$target::malloc:entry +{ + self->msize = arg0; +} + +pid$target::malloc:return +{ + printf("malloc(%#d) = %#p\n", self->msize, arg1); + self->msize = 0; +} + +pid$target::valloc:entry +{ + self->vsize = arg0; +} + +pid$target::valloc:return +/self->vsize/ +{ + printf("valloc(%d) = %#p\n", self->vsize, arg1); + self->vsize = 0; +} + +pid$target::calloc:entry +{ + self->ccount = arg0; + self->csize = arg1; +} + +pid$target::calloc:return +/self->csize/ +{ + printf("calloc(%d, %d) = %#p\n", self->ccount, self->csize, arg1); + self->ccount = 0; + self->csize = 0; +} + +pid$target::realloc:entry +{ + self->raddr = arg0; + self->rsize = arg1; +} + +pid$target::realloc:return +/self->rsize/ +{ + printf("realloc(%#p, %d) = %#p\n", self->raddr, self->rsize, arg1); + self->rsize = 0; + self->raddr = 0; +} + +pid$target::reallocf:entry +{ + self->rfaddr = arg0; + self->rfsize = arg1; +} + +pid$target::reallocf:return +/self->rfsize/ +{ + printf("reallocf(%#p, %d) = %#p\n", self->rfaddr, self->rfsize, arg1); + self->rfaddr = 0; + self->rfsize = 0; +} + +pid$target::free:entry +{ + printf("free(%#p) = 0\n", arg0); +} + From 1ea205a7236a33eca8e03b81315ce4e0590c787b Mon Sep 17 00:00:00 2001 From: dyjakan Date: Thu, 14 May 2015 23:56:00 +0200 Subject: [PATCH 02/19] copy&paste --- dtracetool/README.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 dtracetool/README.md diff --git a/dtracetool/README.md b/dtracetool/README.md new file mode 100644 index 0000000..e3621f5 --- /dev/null +++ b/dtracetool/README.md @@ -0,0 +1,6 @@ +Villoc DTrace Tool +================== + +This is a DTrace tool which aims to create an ltrace compatible output for +heap management functions which can be visualised by villoc. + From 0b056beecd11e9c835f1cb9133a734cc6d18aea5 Mon Sep 17 00:00:00 2001 From: dyjakan Date: Fri, 15 May 2015 15:12:00 +0200 Subject: [PATCH 03/19] valloc() support --- villoc.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/villoc.py b/villoc.py index 67629a8..7994670 100755 --- a/villoc.py +++ b/villoc.py @@ -159,6 +159,9 @@ def malloc(state, ret, size): state.append(Block(ret, size)) +def valloc(state, ret, size): + malloc(state, ret, size) + def calloc(state, ret, nmemb, size): malloc(state, ret, nmemb * size) @@ -200,6 +203,7 @@ def realloc(state, ret, ptr, size): operations = { 'free': free, 'malloc': malloc, + 'valloc': valloc, 'calloc': calloc, 'realloc': realloc, } From daf7559e9640b14688a39dffa7466f3f0570b335 Mon Sep 17 00:00:00 2001 From: dyjakan Date: Fri, 15 May 2015 15:37:00 +0200 Subject: [PATCH 04/19] reallocf() _support_ added --- villoc.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/villoc.py b/villoc.py index 7994670..7887d3e 100755 --- a/villoc.py +++ b/villoc.py @@ -162,6 +162,7 @@ def malloc(state, ret, size): def valloc(state, ret, size): malloc(state, ret, size) + def calloc(state, ret, nmemb, size): malloc(state, ret, nmemb * size) @@ -198,6 +199,13 @@ def realloc(state, ret, ptr, size): state[s].error = True else: state[s] = Block(ret, size, color=match.color) + + +# This is just an empty stub for reallocf(). This is because internally +# reallocf() calls realloc() so we catch it there. +# However, for the sake of completness it's good to have it in the output. +def reallocf(state, ret, ptr, size): + return operations = { @@ -206,6 +214,7 @@ def realloc(state, ret, ptr, size): 'valloc': valloc, 'calloc': calloc, 'realloc': realloc, + 'reallocf': reallocf, } From 52468656a0dee4ced9eb9ba46aa64b5e74fe9dfc Mon Sep 17 00:00:00 2001 From: dyjakan Date: Fri, 15 May 2015 15:47:52 +0200 Subject: [PATCH 05/19] cosmetic changes --- dtracetool/memtrace.d | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/dtracetool/memtrace.d b/dtracetool/memtrace.d index 4a30cb5..71fd5eb 100755 --- a/dtracetool/memtrace.d +++ b/dtracetool/memtrace.d @@ -23,12 +23,6 @@ to a certain degree via DTrace tuning [2] [3]. #pragma D option destructive #pragma D option bufsize=256m -/* -TODO: - o More testing (custom test for each function) - o Customize villoc.py for reallocf() and valloc() - o Do we need all these predicates? -*/ pid$target::malloc:entry { @@ -37,7 +31,7 @@ pid$target::malloc:entry pid$target::malloc:return { - printf("malloc(%#d) = %#p\n", self->msize, arg1); + printf("malloc(%d) = %#p\n", self->msize, arg1); self->msize = 0; } From bc3f089bdbe2a9a24551ed224495c165ed6e869c Mon Sep 17 00:00:00 2001 From: dyjakan Date: Fri, 15 May 2015 15:50:57 +0200 Subject: [PATCH 06/19] example for tests --- dtracetool/tests/test1.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 dtracetool/tests/test1.c diff --git a/dtracetool/tests/test1.c b/dtracetool/tests/test1.c new file mode 100644 index 0000000..1411fe4 --- /dev/null +++ b/dtracetool/tests/test1.c @@ -0,0 +1,37 @@ +#include +#include + +#define DEBUG 0 + +int +main(void) +{ + int *cptr, *mptr, *vptr; + + cptr = calloc(8, 32); + if(DEBUG) + printf("cptr = %p\n", cptr); + + mptr = malloc(64); + if(DEBUG) + printf("mptr = %p\n", mptr); + + mptr = realloc(mptr, 128); + if(DEBUG) + printf("mptr = %p\n", mptr); + + vptr = valloc(64); + if(DEBUG) + printf("vptr = %p\n", vptr); + + vptr = reallocf(vptr, 128); + if(DEBUG) + printf("vptr = %p\n", vptr); + + free(cptr); + free(mptr); + free(vptr); + + return 0; +} + From 32a6fe35cd65a4a48759a49253e08bfcf3969be6 Mon Sep 17 00:00:00 2001 From: dyjakan Date: Fri, 15 May 2015 17:08:53 +0200 Subject: [PATCH 07/19] usage example --- dtracetool/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dtracetool/README.md b/dtracetool/README.md index e3621f5..7116027 100644 --- a/dtracetool/README.md +++ b/dtracetool/README.md @@ -4,3 +4,10 @@ Villoc DTrace Tool This is a DTrace tool which aims to create an ltrace compatible output for heap management functions which can be visualised by villoc. +Usage +----- + +```shell +$ sudo ./memtrace.d -c | ./villoc.py - out.html +``` + From ac0cb8e522b87e725d4339e69620b29b521d5432 Mon Sep 17 00:00:00 2001 From: dyjakan Date: Fri, 15 May 2015 17:31:40 +0200 Subject: [PATCH 08/19] missing predicate; better safe than sorry --- dtracetool/memtrace.d | 1 + 1 file changed, 1 insertion(+) diff --git a/dtracetool/memtrace.d b/dtracetool/memtrace.d index 71fd5eb..358fc53 100755 --- a/dtracetool/memtrace.d +++ b/dtracetool/memtrace.d @@ -30,6 +30,7 @@ pid$target::malloc:entry } pid$target::malloc:return +/self->msize/ { printf("malloc(%d) = %#p\n", self->msize, arg1); self->msize = 0; From 4d479674fc541dcb4cc6a5efa302ae15458a3b15 Mon Sep 17 00:00:00 2001 From: BestPig Date: Fri, 15 May 2015 20:18:46 +0200 Subject: [PATCH 09/19] The dtrace script is now capable of detecting crash of a function call. --- dtracetool/memtrace.d | 94 ++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 27 deletions(-) diff --git a/dtracetool/memtrace.d b/dtracetool/memtrace.d index 358fc53..3deb3a1 100755 --- a/dtracetool/memtrace.d +++ b/dtracetool/memtrace.d @@ -26,72 +26,112 @@ to a certain degree via DTrace tuning [2] [3]. pid$target::malloc:entry { - self->msize = arg0; + msize = arg0; + malloc_fail = 1 } pid$target::malloc:return -/self->msize/ +/msize/ { - printf("malloc(%d) = %#p\n", self->msize, arg1); - self->msize = 0; + printf("malloc(%d) = %#p\n", msize, arg1); + msize = 0; + malloc_fail = 0; } pid$target::valloc:entry { - self->vsize = arg0; + vsize = arg0; + valloc_fail = 1; } pid$target::valloc:return -/self->vsize/ +/vsize/ { - printf("valloc(%d) = %#p\n", self->vsize, arg1); - self->vsize = 0; + printf("valloc(%d) = %#p\n", vsize, arg1); + vsize = 0; + valloc_fail = 0; } pid$target::calloc:entry { - self->ccount = arg0; - self->csize = arg1; + ccount = arg0; + csize = arg1; + calloc_fail = 1; } pid$target::calloc:return -/self->csize/ +/csize/ { - printf("calloc(%d, %d) = %#p\n", self->ccount, self->csize, arg1); - self->ccount = 0; - self->csize = 0; + printf("calloc(%d, %d) = %#p\n", ccount, csize, arg1); + ccount = 0; + csize = 0; + calloc_fail = 0; } pid$target::realloc:entry { - self->raddr = arg0; - self->rsize = arg1; + raddr = arg0; + rsize = arg1; + realloc_fail = 1; } pid$target::realloc:return -/self->rsize/ +/rsize/ { - printf("realloc(%#p, %d) = %#p\n", self->raddr, self->rsize, arg1); - self->rsize = 0; - self->raddr = 0; + printf("realloc(%#p, %d) = %#p\n", raddr, rsize, arg1); + rsize = 0; + raddr = 0; + realloc_fail = 0; } pid$target::reallocf:entry { - self->rfaddr = arg0; - self->rfsize = arg1; + rfaddr = arg0; + rfsize = arg1; + reallocf_fail = 1; } pid$target::reallocf:return -/self->rfsize/ +/rfsize/ { - printf("reallocf(%#p, %d) = %#p\n", self->rfaddr, self->rfsize, arg1); - self->rfaddr = 0; - self->rfsize = 0; + printf("reallocf(%#p, %d) = %#p\n", rfaddr, rfsize, arg1); + rfaddr = 0; + rfsize = 0; + reallocf_fail = 0; } pid$target::free:entry { - printf("free(%#p) = 0\n", arg0); + printf("free(%#p) = \n", arg0); +} + +dtrace:::END +/malloc_fail == 1/ +{ + printf("malloc(%d) = \n", msize); +} + +dtrace:::END +/valloc_fail == 1/ +{ + printf("valloc(%d) = \n", vsize); +} + +dtrace:::END +/calloc_fail == 1/ +{ + printf("calloc(%d, %d) = \n", ccount, csize); +} + +dtrace:::END +/realloc_fail == 1/ +{ + printf("realloc(%#p, %d) = \n", raddr, rsize); +} + +dtrace:::END +/reallocf_fail == 1/ +{ + printf("reallocf(%#p, %d) = \n", rfaddr, rfsize); } From 225f8b61d871b95aa82e7720d186a8bf396e4582 Mon Sep 17 00:00:00 2001 From: dyjakan Date: Fri, 15 May 2015 22:46:54 +0200 Subject: [PATCH 10/19] destructive pragma is not required here --- dtracetool/memtrace.d | 1 - 1 file changed, 1 deletion(-) diff --git a/dtracetool/memtrace.d b/dtracetool/memtrace.d index 3deb3a1..711902e 100755 --- a/dtracetool/memtrace.d +++ b/dtracetool/memtrace.d @@ -20,7 +20,6 @@ to a certain degree via DTrace tuning [2] [3]. /* Re-enable to see potential data drops */ #pragma D option quiet -#pragma D option destructive #pragma D option bufsize=256m From 1364404c6d233284051322af9661cfa5c68af145 Mon Sep 17 00:00:00 2001 From: dyjakan Date: Fri, 15 May 2015 23:01:20 +0200 Subject: [PATCH 11/19] buffer extension is optional as mentioned in the main comment --- dtracetool/memtrace.d | 2 -- 1 file changed, 2 deletions(-) diff --git a/dtracetool/memtrace.d b/dtracetool/memtrace.d index 711902e..acdc9de 100755 --- a/dtracetool/memtrace.d +++ b/dtracetool/memtrace.d @@ -20,8 +20,6 @@ to a certain degree via DTrace tuning [2] [3]. /* Re-enable to see potential data drops */ #pragma D option quiet -#pragma D option bufsize=256m - pid$target::malloc:entry { From e5ade11bc74ab7926611eeb5efee2fe794a86791 Mon Sep 17 00:00:00 2001 From: dyjakan Date: Sat, 16 May 2015 00:49:52 +0200 Subject: [PATCH 12/19] back to the roots --- dtracetool/memtrace.d | 92 ++++++++++++------------------------------- 1 file changed, 26 insertions(+), 66 deletions(-) diff --git a/dtracetool/memtrace.d b/dtracetool/memtrace.d index acdc9de..3e0f650 100755 --- a/dtracetool/memtrace.d +++ b/dtracetool/memtrace.d @@ -23,78 +23,68 @@ to a certain degree via DTrace tuning [2] [3]. pid$target::malloc:entry { - msize = arg0; - malloc_fail = 1 + self->msize = arg0; } pid$target::malloc:return -/msize/ +/self->msize/ { - printf("malloc(%d) = %#p\n", msize, arg1); - msize = 0; - malloc_fail = 0; + printf("malloc(%d) = %#p\n", self->msize, arg1); + self->msize = 0; } pid$target::valloc:entry { - vsize = arg0; - valloc_fail = 1; + self->vsize = arg0; } pid$target::valloc:return -/vsize/ +/self->vsize/ { - printf("valloc(%d) = %#p\n", vsize, arg1); - vsize = 0; - valloc_fail = 0; + printf("valloc(%d) = %#p\n", self->vsize, arg1); + self->vsize = 0; } pid$target::calloc:entry { - ccount = arg0; - csize = arg1; - calloc_fail = 1; + self->ccount = arg0; + self->csize = arg1; } pid$target::calloc:return -/csize/ +/self->csize/ { - printf("calloc(%d, %d) = %#p\n", ccount, csize, arg1); - ccount = 0; - csize = 0; - calloc_fail = 0; + printf("calloc(%d, %d) = %#p\n", self->ccount, self->csize, arg1); + self->ccount = 0; + self->csize = 0; } pid$target::realloc:entry { - raddr = arg0; - rsize = arg1; - realloc_fail = 1; + self->raddr = arg0; + self->rsize = arg1; } pid$target::realloc:return -/rsize/ +/self->rsize/ { - printf("realloc(%#p, %d) = %#p\n", raddr, rsize, arg1); - rsize = 0; - raddr = 0; - realloc_fail = 0; + printf("realloc(%#p, %d) = %#p\n", self->raddr, self->rsize, arg1); + self->rsize = 0; + self->raddr = 0; } pid$target::reallocf:entry { - rfaddr = arg0; - rfsize = arg1; - reallocf_fail = 1; + self->rfaddr = arg0; + self->rfsize = arg1; } pid$target::reallocf:return -/rfsize/ +/self->rfsize/ { - printf("reallocf(%#p, %d) = %#p\n", rfaddr, rfsize, arg1); - rfaddr = 0; - rfsize = 0; - reallocf_fail = 0; + printf("reallocf(%#p, %d) = %#p\n", self->rfaddr, self->rfsize, arg1); + self->rfaddr = 0; + self->rfsize = 0; } pid$target::free:entry @@ -102,33 +92,3 @@ pid$target::free:entry printf("free(%#p) = \n", arg0); } -dtrace:::END -/malloc_fail == 1/ -{ - printf("malloc(%d) = \n", msize); -} - -dtrace:::END -/valloc_fail == 1/ -{ - printf("valloc(%d) = \n", vsize); -} - -dtrace:::END -/calloc_fail == 1/ -{ - printf("calloc(%d, %d) = \n", ccount, csize); -} - -dtrace:::END -/realloc_fail == 1/ -{ - printf("realloc(%#p, %d) = \n", raddr, rsize); -} - -dtrace:::END -/reallocf_fail == 1/ -{ - printf("reallocf(%#p, %d) = \n", rfaddr, rfsize); -} - From d65fe1401924cc02bb117badb864d4027cae2f1b Mon Sep 17 00:00:00 2001 From: dyjakan Date: Sat, 16 May 2015 09:36:59 +0200 Subject: [PATCH 13/19] Fixing realloc/reallocf. This should be applied regardless of the merge. --- villoc.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/villoc.py b/villoc.py index 7887d3e..9f7ff2c 100755 --- a/villoc.py +++ b/villoc.py @@ -187,6 +187,8 @@ def realloc(state, ret, ptr, size): if not ptr: return malloc(state, ret, size) + elif not ret: + return malloc(state, ret, size) elif not size: return free(state, ret, ptr) From 750ee366fdfc426e6f971f38d9f45e5d8071b738 Mon Sep 17 00:00:00 2001 From: dyjakan Date: Sat, 16 May 2015 09:40:47 +0200 Subject: [PATCH 14/19] testing application for memory allocations fails --- dtracetool/tests/test2.c | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 dtracetool/tests/test2.c diff --git a/dtracetool/tests/test2.c b/dtracetool/tests/test2.c new file mode 100644 index 0000000..305f024 --- /dev/null +++ b/dtracetool/tests/test2.c @@ -0,0 +1,67 @@ +#include +#include + +#define DEBUG 0 + +int +main(void) +{ + int *cptr, *mptr, *vptr, *rptr, *rfptr; + + /* Failing calloc */ + cptr = calloc(1337, 0xFFFFFFFFFFFF); + if(DEBUG) + printf("cptr = %p\n", cptr); + + /* Succeeding calloc */ + cptr = calloc(8, 32); + if(DEBUG) + printf("cptr = %p\n", cptr); + + /* Failing malloc */ + mptr = malloc(0xFFFFFFFFFFFFFF); + if(DEBUG) + printf("mptr = %p\n", mptr); + + /* Succeeding malloc */ + mptr = malloc(64); + if(DEBUG) + printf("mptr = %p\n", mptr); + + /* Failing realloc, we want to test if mptr is still valid */ + rptr = realloc(mptr, 0xFFFFFFFFFFFF); + if(DEBUG) + printf("mptr = %p\n", mptr); + + /* Succeeding realloc */ + mptr = realloc(mptr, 128); + if(DEBUG) + printf("mptr = %p\n", mptr); + + /* Failing valloc */ + vptr = valloc(0xFFFFFFFFFFFF); + if(DEBUG) + printf("vptr = %p\n", vptr); + + /* Succeeding valloc */ + vptr = valloc(64); + if(DEBUG) + printf("vptr = %p\n", vptr); + + /* Succeeding reallocf */ + vptr = reallocf(vptr, 128); + if(DEBUG) + printf("vptr = %p\n", vptr); + + /* Failing reallocf, we want to test if vptr is still valid */ + rfptr = reallocf(vptr, 0xFFFFFFFFFFFF); + if(DEBUG) + printf("vptr = %p\n", vptr); + + free(cptr); + free(mptr); +// free(vptr); + + return 0; +} + From 7593a9470bb0281c0db93b26ebc0a139b12e778f Mon Sep 17 00:00:00 2001 From: dyjakan Date: Fri, 26 Jun 2015 15:41:05 +0200 Subject: [PATCH 15/19] minor fix and new test for malloc() crash --- dtracetool/tests/test1.c | 2 ++ dtracetool/tests/test2.c | 2 ++ dtracetool/tests/test3.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 dtracetool/tests/test3.c diff --git a/dtracetool/tests/test1.c b/dtracetool/tests/test1.c index 1411fe4..1291bdb 100644 --- a/dtracetool/tests/test1.c +++ b/dtracetool/tests/test1.c @@ -1,3 +1,5 @@ +/* Testing for each alloc function from libc */ + #include #include diff --git a/dtracetool/tests/test2.c b/dtracetool/tests/test2.c index 305f024..b56d7dd 100644 --- a/dtracetool/tests/test2.c +++ b/dtracetool/tests/test2.c @@ -1,3 +1,5 @@ +/* Testing for fail/success of alloc functions */ + #include #include diff --git a/dtracetool/tests/test3.c b/dtracetool/tests/test3.c new file mode 100644 index 0000000..d9c0bff --- /dev/null +++ b/dtracetool/tests/test3.c @@ -0,0 +1,34 @@ +/* Testing for a crash inside of the malloc() */ + +#include +#include +#include + +int main(int argc, char **argv) +{ + (void) argc, (void) argv; + + void *a, *b, *c; + + a = malloc(48); + b = malloc(48); + c = malloc(48); + + free(a); + + // Let's say we have an underflow on c. This + // is far from the only way to trigger a crash. + memset(c-128, 0xff, 0x200); + + printf("A crash in malloc will be triggered *after* this print.\n"); + malloc(48); + + printf("This shouldn't be reached but it is on OS X (unlike Ubuntu)\n"); + malloc(48); + + printf("However, this isn't reached\n"); + malloc(1337); + + return 0; +} + From db91cedda3d8c1b2c9c50ecbdc6bdbc9366beedf Mon Sep 17 00:00:00 2001 From: dyjakan Date: Fri, 26 Jun 2015 16:01:39 +0200 Subject: [PATCH 16/19] makefile for tests --- dtracetool/tests/Makefile | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 dtracetool/tests/Makefile diff --git a/dtracetool/tests/Makefile b/dtracetool/tests/Makefile new file mode 100644 index 0000000..f67c104 --- /dev/null +++ b/dtracetool/tests/Makefile @@ -0,0 +1,17 @@ +CC = clang + +all: test1 test2 test3 + +test1: test1.c + $(CC) -o test1 test1.c + +test2: test2.c + $(CC) -o test2 test2.c + +test3: test3.c + $(CC) -o test3 test3.c + +clean: + rm test1 + rm test2 + rm test3 \ No newline at end of file From 1c35cc968228f060705c5b7c15486a0fa4db32cc Mon Sep 17 00:00:00 2001 From: dyjakan Date: Fri, 26 Jun 2015 17:23:00 +0200 Subject: [PATCH 17/19] handling of token --- villoc.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/villoc.py b/villoc.py index 9f7ff2c..bb184a7 100755 --- a/villoc.py +++ b/villoc.py @@ -223,6 +223,8 @@ def reallocf(state, ret, ptr, size): def sanitize(x): if x is None: return None + if x == "": + return None if x == "": return 0 return int(x, 0) From f0fd31af287c19c630b3061a4116e6a72d047cbf Mon Sep 17 00:00:00 2001 From: dyjakan Date: Mon, 29 Jun 2015 23:05:38 +0200 Subject: [PATCH 18/19] tested platforms --- dtracetool/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dtracetool/README.md b/dtracetool/README.md index 7116027..005be94 100644 --- a/dtracetool/README.md +++ b/dtracetool/README.md @@ -1,9 +1,11 @@ -Villoc DTrace Tool -================== +DTrace Memory Tracer +==================== This is a DTrace tool which aims to create an ltrace compatible output for heap management functions which can be visualised by villoc. +Tested only on OS X. Other supported platforms may require modificatons. + Usage ----- From c75de68c0fbc3a15d1d7d04c81ad03ca4ff9f1c0 Mon Sep 17 00:00:00 2001 From: dyjakan Date: Mon, 29 Jun 2015 23:06:56 +0200 Subject: [PATCH 19/19] Major change. Adjusted to catch *alloc fails. --- dtracetool/memtrace.d | 109 +++++++++++++++++++++++++++++++----------- 1 file changed, 82 insertions(+), 27 deletions(-) diff --git a/dtracetool/memtrace.d b/dtracetool/memtrace.d index 3e0f650..1403cee 100755 --- a/dtracetool/memtrace.d +++ b/dtracetool/memtrace.d @@ -20,75 +20,130 @@ to a certain degree via DTrace tuning [2] [3]. /* Re-enable to see potential data drops */ #pragma D option quiet +/* Globals for alloc functions args. Explicitly typed to avoid errors. */ +size_t malloc_size; +size_t valloc_size; +size_t calloc_count; +size_t calloc_size; +int64_t realloc_addr; +size_t realloc_size; +int64_t reallocf_addr; +size_t reallocf_size; +int64_t free_addr; + +BEGIN +{ + /* Flags for failure inside of the functions */ + /* However, we're using them also for predicates. This is a hack. */ + malloc_fail = 0; + valloc_fail = 0; + calloc_fail = 0; + realloc_fail = 0; + reallocf_fail = 0; + free_fail = 0; +} + pid$target::malloc:entry { - self->msize = arg0; + malloc_size = arg0; + malloc_fail = 1; } pid$target::malloc:return -/self->msize/ +/malloc_fail/ { - printf("malloc(%d) = %#p\n", self->msize, arg1); - self->msize = 0; + printf("malloc(%d) = %#p\n", malloc_size, arg1); + malloc_fail = 0; } pid$target::valloc:entry { - self->vsize = arg0; + valloc_size = arg0; + valloc_fail = 1; } pid$target::valloc:return -/self->vsize/ +/valloc_fail/ { - printf("valloc(%d) = %#p\n", self->vsize, arg1); - self->vsize = 0; + printf("valloc(%d) = %#p\n", valloc_size, arg1); + valloc_fail = 0; } pid$target::calloc:entry { - self->ccount = arg0; - self->csize = arg1; + calloc_count = arg0; + calloc_size = arg1; + calloc_fail = 1; } pid$target::calloc:return -/self->csize/ +/calloc_fail/ { - printf("calloc(%d, %d) = %#p\n", self->ccount, self->csize, arg1); - self->ccount = 0; - self->csize = 0; + printf("calloc(%d, %d) = %#p\n", calloc_count, calloc_size, arg1); + calloc_fail = 0; } pid$target::realloc:entry { - self->raddr = arg0; - self->rsize = arg1; + realloc_addr = arg0; + realloc_size = arg1; + realloc_fail = 1; } pid$target::realloc:return -/self->rsize/ +/realloc_fail/ { - printf("realloc(%#p, %d) = %#p\n", self->raddr, self->rsize, arg1); - self->rsize = 0; - self->raddr = 0; + printf("realloc(%#p, %d) = %#p\n", realloc_addr, realloc_size, arg1); + realloc_fail = 0; } pid$target::reallocf:entry { - self->rfaddr = arg0; - self->rfsize = arg1; + reallocf_addr = arg0; + reallocf_size = arg1; + reallocf_fail = 1; } pid$target::reallocf:return -/self->rfsize/ +/reallocf_fail/ { - printf("reallocf(%#p, %d) = %#p\n", self->rfaddr, self->rfsize, arg1); - self->rfaddr = 0; - self->rfsize = 0; + printf("reallocf(%#p, %d) = %#p\n", reallocf_addr, reallocf_size, arg1); + reallocf_fail = 0; } pid$target::free:entry { - printf("free(%#p) = \n", arg0); + free_addr = arg0; + printf("free(%#p) = \n", free_addr); +} + +END +/malloc_fail/ +{ + printf("malloc(%d) = \n", malloc_size); +} + +END +/valloc_fail/ +{ + printf("valloc(%d) = \n", valloc_size); } +END +/calloc_fail/ +{ + printf("calloc(%d, %d) = \n", calloc_count, calloc_size); +} + +END +/realloc_fail/ +{ + printf("realloc(%#p, %d) = \n", realloc_addr, realloc_size); +} + +END +/reallocf_fail/ +{ + printf("realloc(%#p, %d) = \n", reallocf_addr, reallocf_size); +}