diff --git a/.release b/.release index 7bf6d94..0885d1b 100644 --- a/.release +++ b/.release @@ -1,3 +1,3 @@ -date=Fri Mar 6 20:00:45 GMT 2015 -release=dtrace-20150306 -build=484 +date=Mon Jun 13 23:21:08 BST 2016 +release=dtrace-20160613 +build=499 diff --git a/Changes b/Changes index 3641a89..bc57312 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,45 @@ +Mon Jan 11 21:17:16 2016 fox + + 868* driver/intr.c + Handle 3.10 (centos 7) kernels for store_gdt. + +Mon Dec 28 19:47:46 2015 fox + + 867* driver/dtrace.c + driver/dtrace_linux.c + driver/fasttrap_isa.c + Fixes for fasttrap (pid provider): + + dtrace -n pidXXXX:::entry + + will work but *WILL* cause any fork/cloned child to terminate + with a SIGTRAP event because we dont latch onto the children + and remove the embedded breakpoints. (Needs more R&D to determine + how to do this in Linux). + + This should work, but if it fails, send me a dmesg output - + the patching of the page tables may/will fail when allocating + a private buffer - but this may depend on VM, Xen or real HW. + + 866* README.md + driver/intr_x86-64.S + driver/systrace.c + driver/systrace_asm.S + driver/x_call.c + libdtrace/drti.c + libproc/common/Psymtab.c + tools/load.pl + tools/mkport.pl + tools/mkrelease.pl + Fix for system_unbound_workq vs system_unbound_wq. + Fix silly in Psymtab.c leading to SIGSEGV. + +Tue May 19 21:20:33 2015 fox + + 865* driver/prov_proc.c + Fix for 3.18/19 kernels (not sure I got the change right - 3.16 + is not affected, but 3.19 - Ubuntu 15.04 - is). + Tue Mar 3 22:33:03 2015 fox 864* README diff --git a/README b/README.md similarity index 89% rename from README rename to README.md index 09fdc62..a9b7c46 100644 --- a/README +++ b/README.md @@ -1,20 +1,20 @@ Linux port of DTrace -Mar 2015 +Dec 2015 Paul D. Fox paul.d.fox@gmail.com http://www.twitter.com/crispeditor -http://www.crisp.demon.co.uk +http://www.crispeditor.co.uk Blog - latest news and stuff about the dtrace project: http://crtags.blogspot.com/ - http://www.crisp.demon.co.uk/blog/ + http://www.crispeditor.co.uk/blog/ Download dtrace tarballs for linux here: https://github.com/dtrace4linux/linux - ftp://crisp.publicvm.com/pub/release/website/dtrace + ftp://crispeditor.co.uk/pub/release/website/dtrace Introduction ============ @@ -39,7 +39,8 @@ but it can help guage interest and appreciation if you do. You can pay by visiting the link below and clicking on "Donate", or use this reference for donations: - foxpaypal@crisp.demon.co.uk + * paul.d.fox@gmail.com + * [Paypal](https://www.paypal.com/cgi-bin/webscr?business=paul.d.fox@gmail.com&cmd=_xclick¤cy_code=GBP&amount=15&item_name=DTrace) Licensing ========= @@ -93,7 +94,7 @@ list may be incomplete depending on the version of your kernel/distro. $ make install $ make load (need to be root or have sudo access) -If the libdwarf package installed on the system is to old +If the libdwarf package installed on the system is too old it still compiles without any problem, but you will get runtime errors from the io.d and/or sched.d files due to undefined kernel structure definitions. @@ -190,31 +191,31 @@ a kernel build environment is available. INSTALLATION ============ -Run 'make' with no arguments to see the current options. You -may need to run one of the tools/get-deps scripts for your OS +Run `make` with no arguments to see the current options. You +may need to run one of the `tools/get-deps` scripts for your OS flavor to ensure you have the tools and kernel build environment for your kernel. -make all - to compile the drivers and user space commands. Check the file - Packages, for hints on what you need (not much, but libelf, kernel - source, flex/yacc -- bison will do). + make all + to compile the drivers and user space commands. Check the file + Packages, for hints on what you need (not much, but libelf, kernel + source, flex/yacc -- bison will do). -make install - Copy dtrace binary and driver to correct install location. + make install + Copy dtrace binary and driver to correct install location. -make load - To load the drivers, and then you can play with cmd/dtrace/dtrace. + make load + To load the drivers, and then you can play with cmd/dtrace/dtrace. -make unl - to unload the drivers. + make unl + to unload the drivers. -make test - To run the userland cmd/dtrace regression test + make test + To run the userland cmd/dtrace regression test To build the userland (command and object file etc) and the kernel module for different architectures, set the environment -variable BUILD_ARCH appropriately and then use the make targets +variable `BUILD_ARCH` appropriately and then use the make targets separately. This example is for building on a system with a 64-bit kernel, diff --git a/Status.txt b/Status.txt index 19a25b3..a76320c 100644 --- a/Status.txt +++ b/Status.txt @@ -3,6 +3,10 @@ a very good suggestion, so that people dont have to figure out from my titbits in the blog (http://www.crtags.blogspot.com), what works and what doesnt work. +20160818 PDF + + o Verified it works on Ubuntu 16.04 - 4.4 kernel. + 20150306 PDF o Took out broken "break" which caused xcall to randomly not work, @@ -22,7 +26,7 @@ doesnt work. Working Features - o Works on AS4/64 bit kernels, Ubuntu 8.xx - 14.xx (32-bit and 64-bit). + o Works on AS4/64 bit kernels, Ubuntu 8.xx - 16.xx (32-bit and 64-bit). Not every kernel version tested, but should build on at least 2.6.12 onwards. o Tested up to 3.16 kernels, but not proven/tested under later kernels. diff --git a/driver/ctf_subr.c b/driver/ctf_subr.c index 527aca6..867a4ee 100644 --- a/driver/ctf_subr.c +++ b/driver/ctf_subr.c @@ -42,6 +42,9 @@ void * ctf_data_alloc(size_t size) { +# if !defined(__GFP_WAIT) +# define __GFP_WAIT __GFP_RECLAIM +# endif void *buf = kmalloc(size, GFP_KERNEL & ~__GFP_WAIT); if (buf == NULL) diff --git a/driver/cyclic_linux.c b/driver/cyclic_linux.c index 08f9c93..c16de60 100644 --- a/driver/cyclic_linux.c +++ b/driver/cyclic_linux.c @@ -111,6 +111,9 @@ static int (*fn_hrtimer_init)(struct hrtimer *timer, clockid_t which_clock, static int (*fn_hrtimer_cancel)(struct hrtimer *); static int (*fn_hrtimer_start)(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode); +static int (*fn_hrtimer_start_range_ns)(struct hrtimer *timer, ktime_t tim, + unsigned long delta_ns, + const enum hrtimer_mode mode); static u64 (*fn_hrtimer_forward)(struct hrtimer *timer, ktime_t now, ktime_t interval); #define TMR_ALIVE 1 @@ -144,10 +147,10 @@ init_cyclic() fn_hrtimer_cancel = get_proc_addr("hrtimer_cancel"); fn_hrtimer_init = get_proc_addr("hrtimer_init"); fn_hrtimer_start = get_proc_addr("hrtimer_start"); - fn_hrtimer_start = get_proc_addr("hrtimer_start"); + fn_hrtimer_start_range_ns = get_proc_addr("hrtimer_start_range_ns"); fn_hrtimer_forward = get_proc_addr("hrtimer_forward"); - if (fn_hrtimer_start == NULL) { + if (fn_hrtimer_start == NULL && fn_hrtimer_start_range_ns == NULL) { printk(KERN_WARNING "dtracedrv: Cannot locate hrtimer in this kernel\n"); return FALSE; } @@ -187,7 +190,11 @@ static void cyclic_tasklet_func(unsigned long arg) break; ptr = &cp->c_htp; - kt.tv64 = cp->c_time.cyt_interval; + #if(LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)) + kt.tv64 = cp->c_time.cyt_interval; + #else + kt = cp->c_time.cyt_interval; + #endif /***********************************************/ /* Invoke the callback. */ /***********************************************/ @@ -226,7 +233,10 @@ static void cyclic_tasklet_func(unsigned long arg) #else ptr->expires = ktime_add_ns(ptr->expires, kt.tv64); #endif - fn_hrtimer_start(&cp->c_htp, kt, HRTIMER_MODE_REL); + if (fn_hrtimer_start) + fn_hrtimer_start(&cp->c_htp, kt, HRTIMER_MODE_REL); + else if (fn_hrtimer_start_range_ns) + fn_hrtimer_start(&cp->c_htp, kt, 0, HRTIMER_MODE_REL); # endif cp->c_state = TMR_ALIVE; } @@ -320,18 +330,25 @@ cyclic_add(cyc_handler_t *hdrl, cyc_time_t *t) } cnt_timer_add++; - kt.tv64 = t->cyt_interval; + #if(LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0)) + kt.tv64 = t->cyt_interval; + #else + kt = t->cyt_interval; + #endif cp->c_hdlr = *hdrl; cp->c_time = *t; - cp->c_sec = kt.tv64 / (1000 * 1000 * 1000); - cp->c_nsec = kt.tv64 % (1000 * 1000 * 1000); + cp->c_sec = ktime_to_ns(kt) / (1000 * 1000 * 1000); + cp->c_nsec = ktime_to_ns(kt) % (1000 * 1000 * 1000); cp->c_state = TMR_ALIVE; fn_hrtimer_init(&cp->c_htp, CLOCK_MONOTONIC, HRTIMER_MODE_REL); /* cp->c_htp.cb_mode = HRTIMER_CB_SOFTIRQ;*/ cp->c_htp.function = be_callback; - fn_hrtimer_start(&cp->c_htp, kt, HRTIMER_MODE_REL); + if (fn_hrtimer_start) + fn_hrtimer_start(&cp->c_htp, kt, HRTIMER_MODE_REL); + else + fn_hrtimer_start_range_ns(&cp->c_htp, kt, 0, HRTIMER_MODE_REL); return (cyclic_id_t) cp; } @@ -462,4 +479,3 @@ cyclic_remove(cyclic_id_t id) } } # endif - diff --git a/driver/dtrace.c b/driver/dtrace.c index c83ba3b..22430ec 100644 --- a/driver/dtrace.c +++ b/driver/dtrace.c @@ -11123,7 +11123,7 @@ dtrace_buffer_switch(dtrace_buffer_t *buf) ASSERT(!(buf->dtb_flags & DTRACEBUF_RING)); cookie = dtrace_interrupt_disable(); -dtrace_printf("buffersw\n"); +//dtrace_printf("buffersw\n"); buf->dtb_tomax = xamot; buf->dtb_xamot = tomax; buf->dtb_xamot_drops = buf->dtb_drops; @@ -16785,7 +16785,7 @@ PRINT_CASE(DTRACEIOC_DOFGET); } else { buf = &state->dts_aggbuffer[desc.dtbd_cpu]; } -printk("snap cpu=%d flags=%x sz=%x\n", desc.dtbd_cpu, buf->dtb_flags, buf->dtb_offset); +//printk("snap cpu=%d flags=%x sz=%x\n", desc.dtbd_cpu, buf->dtb_flags, buf->dtb_offset); if (buf->dtb_flags & (DTRACEBUF_RING | DTRACEBUF_FILL)) { size_t sz = buf->dtb_offset; diff --git a/driver/dtrace_linux.c b/driver/dtrace_linux.c index 560d8ac..84f2af1 100644 --- a/driver/dtrace_linux.c +++ b/driver/dtrace_linux.c @@ -762,7 +762,7 @@ dtrace_linux_init(void) } # if defined(__arm__) ktime_get_ptr = (ktime_t (*)(void)) get_proc_addr("ktime_get"); - # define rdtscll(t) t = ktime_get_ptr().tv64 + # define rdtscll(t) t = ktime_to_ns(ktime_get_ptr()) # define __flush_tlb_all() local_flush_tlb_all() # define _PAGE_NX 0 # define _PAGE_RW 0 @@ -1472,7 +1472,13 @@ static pte_t *(*lookup_address)(void *, int *); } addr = (unsigned long) addr & ~(PAGESIZE-1); - kpte = lookup_address((void *) addr, &level); + /***********************************************/ + /* Avoid panic if we can help it. */ + /***********************************************/ + if ((kpte = lookup_address((void *) addr, &level)) == NULL) { + printk("mem_set_perms: %p - not found\n", addr); + return 0; + } old_pte = *kpte; new_prot = pte_pgprot(old_pte); pgprot_val(new_prot) |= _PAGE_RW; @@ -3240,4 +3246,3 @@ static void __exit dtracedrv_exit(void) } module_init(dtracedrv_init); module_exit(dtracedrv_exit); - diff --git a/driver/fasttrap_isa.c b/driver/fasttrap_isa.c index 5b69ac6..4420cf6 100644 --- a/driver/fasttrap_isa.c +++ b/driver/fasttrap_isa.c @@ -1002,6 +1002,7 @@ fasttrap_do_seg(fasttrap_tracepoint_t *tp, struct regs *rp, uintptr_t *addr) /**********************************************************************/ /* Temporary hack. */ /**********************************************************************/ +/* #undef fasttrap_copyout int z = 0; int fff(void *a, void *b, int c, int line) @@ -1013,6 +1014,7 @@ int fff(void *a, void *b, int c, int line) return 0; } #define fasttrap_copyout(a,b, c) fff(a, b, c, __LINE__) +*/ int fasttrap_pid_probe(struct regs *rp) @@ -1601,6 +1603,10 @@ PRINT_CASE(FASTTRAP_T_COMMON); up_write(¤t->mm->mmap_sem); } printk("private-alloc %p\n", p->p_private_page); + /***********************************************/ + /* Bad news if we cannot allocate the */ + /* private page. */ + /***********************************************/ addr = (uintptr_t) p->p_private_page; } diff --git a/driver/fbt_linux.c b/driver/fbt_linux.c index f9b0448..78a4492 100644 --- a/driver/fbt_linux.c +++ b/driver/fbt_linux.c @@ -388,10 +388,16 @@ fbt_provide_module(void *arg, struct modctl *ctl) { int i; struct module *mp = (struct module *) ctl; char *modname = mp->name; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) + char *str = mp->kallsyms->strtab; +#else char *str = mp->strtab; +#endif char *name; par_module_t *pmp; int ret; + unsigned nsyms; # if 0 struct module *mp = ctl->mod_mp; @@ -459,12 +465,22 @@ TODO(); return; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) + nsyms = mp->kallsyms->num_symtab; +#else + nsyms = mp->num_symtab; +#endif + if (dtrace_here) - printk("%s(%d):modname=%s num_symtab=%u\n", dtrace_basename(__FILE__), __LINE__, modname, (unsigned) mp->num_symtab); + printk("%s(%d):modname=%s num_symtab=%u\n", dtrace_basename(__FILE__), __LINE__, modname, nsyms); - for (i = 1; i < mp->num_symtab; i++) { + for (i = 1; i < nsyms; i++) { uint8_t *instr, *limit; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) + Elf_Sym *sym = (Elf_Sym *) &mp->kallsyms->symtab[i]; +#else Elf_Sym *sym = (Elf_Sym *) &mp->symtab[i]; +#endif int dtrace_here = 0; if (strcmp(modname, "dummy") == 0) dtrace_here = 1; @@ -577,11 +593,16 @@ if (strcmp(modname, "dummy") == 0) dtrace_here = 1; /* if that page is now used by some other */ /* driver. */ /***********************************************/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) + if (within_module_init(instr, mp)) + continue; +#else if (mp->module_init && mp->init_size && instr >= (uint8_t *) mp->module_init && instr < (uint8_t *) mp->module_init + mp->init_size) { continue; } +#endif /***********************************************/ /* We do have syms that appear to point to */ diff --git a/driver/instr_linux.c b/driver/instr_linux.c index a72b7c6..4e87628 100644 --- a/driver/instr_linux.c +++ b/driver/instr_linux.c @@ -292,8 +292,13 @@ instr_provide_module(void *arg, struct modctl *ctl) { int i; struct module *mp = (struct module *) ctl; char *modname = mp->name; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) + char *str = mp->kallsyms->strtab; +#else char *str = mp->strtab; +#endif char *name; + unsigned nsyms; par_module_t *pmp; int init; @@ -312,14 +317,23 @@ instr_provide_module(void *arg, struct modctl *ctl) return; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) + nsyms = mp->kallsyms->num_symtab; +#else + nsyms = mp->num_symtab; +#endif if (dtrace_here) - printk("%s(%d):modname=%s num_symtab=%u\n", __FILE__, __LINE__, modname, (unsigned) mp->num_symtab); + printk("%s(%d):modname=%s num_symtab=%u\n", __FILE__, __LINE__, modname, nsyms); if (strcmp(modname, "dtracedrv") == 0) return; - for (i = 1; i < mp->num_symtab; i++) { + for (i = 1; i < nsyms; i++) { uint8_t *instr, *limit; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0) + Elf_Sym *sym = (Elf_Sym *) &mp->kallsyms->symtab[i]; +#else Elf_Sym *sym = (Elf_Sym *) &mp->symtab[i]; +#endif int dtrace_here = 0; if (strcmp(modname, "dummy") == 0) dtrace_here = 1; diff --git a/driver/intr.c b/driver/intr.c index 7956278..5c2483e 100644 --- a/driver/intr.c +++ b/driver/intr.c @@ -7,7 +7,7 @@ /* */ /* License: CDDL */ /* */ -/* $Header: Last edited: 12-Oct-2013 1.18 $ */ +/* $Header: Last edited: 11-Jan-2016 1.19 $ */ /**********************************************************************/ #include @@ -48,7 +48,7 @@ #define store_idt(ptr) asm volatile("sidt %0":"=m" (*ptr)) #endif -#if !defined(store_gdt) && LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0) +#if !defined(store_gdt) && LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0) /***********************************************/ /* Xen removed this - oh, so nice of you. */ /* Not! We want the GDT to debug dtrace, so */ diff --git a/driver/intr_x86-64.S b/driver/intr_x86-64.S index acdba57..298259e 100644 --- a/driver/intr_x86-64.S +++ b/driver/intr_x86-64.S @@ -53,7 +53,7 @@ #include #include -#include +/*#include */ #include #ifdef CONFIG_PARAVIRT # include diff --git a/driver/prov_proc.c b/driver/prov_proc.c index e9e4b77..0e25a87 100644 --- a/driver/prov_proc.c +++ b/driver/prov_proc.c @@ -7,7 +7,7 @@ /*--------------------------------------------------------------------*/ /* Description: proc::: provider callbacks */ /*--------------------------------------------------------------------*/ -/* $Header: Last edited: 15-Feb-2015 1.2 $ */ +/* $Header: Last edited: 19-May-2015 1.3 $ */ /**********************************************************************/ #include @@ -42,8 +42,13 @@ psinfo_arg(int n, struct pt_regs *regs) ps->pr_egid = current->egid; #endif ps->pr_addr = current; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0) + ps->pr_start.tv_sec = current->start_time / (1000 * 1000 * 1000); + ps->pr_start.tv_nsec = current->start_time % (1000 * 1000 * 1000); +#else ps->pr_start = current->start_time; - +#endif return (uintptr_t) ps; } diff --git a/driver/systrace.c b/driver/systrace.c index 42350bc..a0f3339 100644 --- a/driver/systrace.c +++ b/driver/systrace.c @@ -304,8 +304,8 @@ static int64_t (*sys32_sigreturn_ptr)(uintptr_t, uintptr_t, uintptr_t, uintptr_t static int64_t (*sys_vfork_ptr)(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t); char *int_ret_from_sys_call_ptr; -static char *ptregscall_common_ptr; -static char *ia32_ptregs_common_ptr; +char *ptregscall_common_ptr; +char *ia32_ptregs_common_ptr; # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) # define HAVE_SAVE_REST 1 static char *save_rest_ptr; @@ -1217,7 +1217,8 @@ dtrace_systrace_syscall_execve(uintptr_t flags, uintptr_t stack_start, uintptr_t regs, uintptr_t stack_size, uintptr_t parent_tidptr, uintptr_t child_tidptr) { dtrace_id_t id; - struct pt_regs *regs = task_pt_regs(current); + + regs = task_pt_regs(current); TRACE_BEFORE(__NR_execve, flags, stack_start, regs, stack_size, parent_tidptr, child_tidptr); diff --git a/driver/systrace_asm.S b/driver/systrace_asm.S index 4fd5a63..76a49c0 100644 --- a/driver/systrace_asm.S +++ b/driver/systrace_asm.S @@ -20,7 +20,7 @@ #include #include #include -#include +/*#include */ #include #include #include diff --git a/driver/taskq.c b/driver/taskq.c index f82b04e..99b15b4 100644 --- a/driver/taskq.c +++ b/driver/taskq.c @@ -272,6 +272,9 @@ taskq_dispatch2(taskq_t *tq, task_func_t func, void *arg, uint_t flags, unsigned if (!taskq_enabled) return 0; +# if !defined(__GFP_WAIT) +# define __GFP_WAIT __GFP_RECLAIM +# endif work = (my_work_t *)kmalloc(sizeof(my_work_t), GFP_KERNEL & ~__GFP_WAIT); if (work == NULL) { printk("taskq_dispatch: couldnt alloc work buffer\n"); diff --git a/driver/vminfo.c b/driver/vminfo.c index d89ad20..f408616 100644 --- a/driver/vminfo.c +++ b/driver/vminfo.c @@ -109,18 +109,30 @@ void vminfo_init(void) sdt_add_locator(vm_event_addr(PGDEACTIVATE), "vminfo:::pgdeactivate"); sdt_add_locator(vm_event_addr(PGFAULT), "vminfo:::pgfault"); sdt_add_locator(vm_event_addr(PGMAJFAULT), "vminfo:::pgmajfault"); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + sdt_add_locator(vm_event_addr(PGREFILL), "vminfo:::pgrefill"); +#else sdt_add_locator(vm_event_addr(PGREFILL_NORMAL), "vminfo:::pgrefill"); sdt_add_locator(vm_event_addr(PGREFILL_MOVABLE), "vminfo:::pgrefill"); +#endif # if LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0) sdt_add_locator(vm_event_addr(PGSTEAL_NORMAL), "vminfo:::pgsteal"); sdt_add_locator(vm_event_addr(PGSTEAL_MOVABLE), "vminfo:::pgsteal"); sdt_add_locator(vm_event_addr(KSWAPD_STEAL), "vminfo:::kswapd_steal"); #endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + sdt_add_locator(vm_event_addr(PGSCAN_KSWAPD), "vminfo:::pgscan_kswapd"); +#else sdt_add_locator(vm_event_addr(PGSCAN_KSWAPD_NORMAL), "vminfo:::pgscan_kswapd"); sdt_add_locator(vm_event_addr(PGSCAN_KSWAPD_MOVABLE), "vminfo:::pgscan_kswapd"); +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + sdt_add_locator(vm_event_addr(PGSCAN_DIRECT), "vminfo:::pgscan_direct"); +#else sdt_add_locator(vm_event_addr(PGSCAN_DIRECT_NORMAL), "vminfo:::pgscan_direct"); sdt_add_locator(vm_event_addr(PGSCAN_DIRECT_MOVABLE), "vminfo:::pgscan_direct"); +#endif #ifdef CONFIG_NUMA sdt_add_locator(vm_event_addr(PGSCAN_ZONE_RECLAIM_FAILED), "vminfo:::pgscan_zone_reclaim_failed"); @@ -138,8 +150,13 @@ void vminfo_init(void) /*sdt_add_locator(vm_event_addr(KSWAPD_SKIP_CONGESTION_WAIT), "vminfo:::kswapd_skip_congestion_wait");*/ #endif sdt_add_locator(vm_event_addr(PAGEOUTRUN), "vminfo:::pageoutrun"); - sdt_add_locator(vm_event_addr(ALLOCSTALL), "vminfo:::allocstall"); sdt_add_locator(vm_event_addr(PGROTATED), "vminfo:::pgrotated"); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + sdt_add_locator(vm_event_addr(ALLOCSTALL_NORMAL), "vminfo:::allocstall"); + sdt_add_locator(vm_event_addr(ALLOCSTALL_MOVABLE), "vminfo:::allocstall"); +#else + sdt_add_locator(vm_event_addr(ALLOCSTALL), "vminfo:::allocstall"); +#endif #ifdef CONFIG_COMPACTION #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) @@ -173,7 +190,11 @@ void vminfo_init(void) sdt_add_locator(vm_event_addr(THP_FAULT_FALLBACK), "vminfo:::thp_fault_fallback"); sdt_add_locator(vm_event_addr(THP_COLLAPSE_ALLOC), "vminfo:::thp_collapse_alloc"); sdt_add_locator(vm_event_addr(THP_COLLAPSE_ALLOC_FAILED), "vminfo:::thp_collapse_alloc_failed"); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + sdt_add_locator(vm_event_addr(THP_SPLIT_PAGE), "vminfo:::thp_split"); + #else sdt_add_locator(vm_event_addr(THP_SPLIT), "vminfo:::thp_split"); + #endif # endif dtrace_parse_kernel(PARSE_GS_INC, vminfo_instr_callback, 0); # endif /* if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) */ diff --git a/driver/x_call.c b/driver/x_call.c index d767508..3a7e809 100644 --- a/driver/x_call.c +++ b/driver/x_call.c @@ -50,6 +50,11 @@ typedef struct apic_ops apic_t; typedef struct apic apic_t; #endif +# if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0) +# define cpus_clear(x) cpumask_clear(&(x)) +# define cpu_set(c, mask) cpumask_set_cpu(c, &(mask)) +#endif + apic_t *hello_apic; /* Define this because apic.h is broken when facing a */ /* non-GPL driver. We get an undefined, so define it. */ /* We use dynamic lookup instead. */ diff --git a/libctf/makefile b/libctf/makefile index b839337..2c7e259 100644 --- a/libctf/makefile +++ b/libctf/makefile @@ -5,6 +5,7 @@ CPPFLAGS += -I../common -I../common/ctf -I../uts/common/ \ -I../linux -DCTF_OLD_VERSIONS $(PTR32) CPPFLAGS += -D_LARGEFILE_SOURCE=1 -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 BINDIR = ../$(BUILD_DIR) +ARFLAGS=Urv COMMON_OBJS = \ ctf_create.o \ @@ -36,47 +37,47 @@ $(BINDIR)/libctf.a: \ $(BINDIR)/libctf.a(ctf_create.o): $(COMMON)/ctf_create.c $(CC) $(CPPFLAGS) -c $< - $(AR) rv $(BINDIR)/libctf.a ctf_create.o + $(AR) $(ARFLAGS) $(BINDIR)/libctf.a ctf_create.o rm -f ctf_create.o $(BINDIR)/libctf.a(ctf_error.o): $(COMMON)/ctf_error.c $(CC) $(CPPFLAGS) -c $< - $(AR) rv $(BINDIR)/libctf.a ctf_error.o + $(AR) $(ARFLAGS) $(BINDIR)/libctf.a ctf_error.o rm -f ctf_error.o $(BINDIR)/libctf.a(ctf_hash.o): $(COMMON)/ctf_hash.c $(CC) $(CPPFLAGS) -c $< - $(AR) rv $(BINDIR)/libctf.a ctf_hash.o + $(AR) $(ARFLAGS) $(BINDIR)/libctf.a ctf_hash.o rm -f ctf_hash.o $(BINDIR)/libctf.a(ctf_labels.o): $(COMMON)/ctf_labels.c $(CC) $(CPPFLAGS) -c $< - $(AR) rv $(BINDIR)/libctf.a ctf_labels.o + $(AR) $(ARFLAGS) $(BINDIR)/libctf.a ctf_labels.o rm -f ctf_labels.o $(BINDIR)/libctf.a(ctf_lookup.o): $(COMMON)/ctf_lookup.c $(CC) $(CPPFLAGS) -c $< - $(AR) rv $(BINDIR)/libctf.a ctf_lookup.o + $(AR) $(ARFLAGS) $(BINDIR)/libctf.a ctf_lookup.o rm -f ctf_lookup.o $(BINDIR)/libctf.a(ctf_open.o): $(COMMON)/ctf_open.c $(CC) $(CPPFLAGS) -c $< - $(AR) rv $(BINDIR)/libctf.a ctf_open.o + $(AR) $(ARFLAGS) $(BINDIR)/libctf.a ctf_open.o rm -f ctf_open.o $(BINDIR)/libctf.a(ctf_types.o): $(COMMON)/ctf_types.c $(CC) $(CPPFLAGS) -c $< - $(AR) rv $(BINDIR)/libctf.a ctf_types.o + $(AR) $(ARFLAGS) $(BINDIR)/libctf.a ctf_types.o rm -f ctf_types.o $(BINDIR)/libctf.a(uncompress.o): uncompress.c $(CC) $(CPPFLAGS) -c $< - $(AR) rv $(BINDIR)/libctf.a uncompress.o + $(AR) $(ARFLAGS) $(BINDIR)/libctf.a uncompress.o rm -f uncompress.o $(BINDIR)/libctf.a(ctf_util.o): $(COMMON)/ctf_util.c $(CC) $(CPPFLAGS) -c $< - $(AR) rv $(BINDIR)/libctf.a ctf_util.o + $(AR) $(ARFLAGS) $(BINDIR)/libctf.a ctf_util.o rm -f ctf_util.o clean: diff --git a/libdtrace/drti.c b/libdtrace/drti.c index fb224b1..12e3236 100644 --- a/libdtrace/drti.c +++ b/libdtrace/drti.c @@ -198,7 +198,19 @@ dtrace_dof_init(void) #endif dh.dofhp_dof = (uintptr_t)dof; +#if defined(linux) + /***********************************************/ + /* Avoid causing a core dump, as reported */ + /* by Martin Englund when compiling Ruby. */ + /***********************************************/ + if (lmp == NULL) { + dprintf1(1, "drti: lmp is null - giving up"); + return; + } dh.dofhp_addr = elf->e_type == ET_DYN ? lmp->l_addr : 0; +#else + dh.dofhp_addr = elf->e_type == ET_DYN ? lmp->l_addr : 0; +#endif if (lmid == 0) { (void) snprintf(dh.dofhp_mod, sizeof (dh.dofhp_mod), diff --git a/libdtrace/makefile b/libdtrace/makefile index c56a583..77e62e0 100644 --- a/libdtrace/makefile +++ b/libdtrace/makefile @@ -1,3 +1,4 @@ +ARFLAGS=Urv CC=gcc -g $(BUILD_BITS) CPPFLAGS += -I. \ -I../../common/ctf \ @@ -88,14 +89,14 @@ $(BINDIR)/dt_grammar.h $(LIB)(dt_grammar.o): dt_grammar.y $(H) mv y.tab.h $(BINDIR)/dt_grammar.h mv y.tab.c dt_grammar.c $(CC) -DYYDEBUG=1 -DYYERROR_VERBOSE $(CPPFLAGS) -c dt_grammar.c - ar rv $(LIB) dt_grammar.o + ar $(ARFLAGS) $(LIB) dt_grammar.o -rm -f dt_grammar.c dt_grammar.o #dt_grammar.h: $(LIB)(dt_grammar.o) $(LIB)(dt_lex.o): $(BINDIR)/dt_grammar.h $(BINDIR)/dt_lex.c $(H) $(CC) $(CPPFLAGS) -c $(BINDIR)/dt_lex.c - ar rv $(LIB) dt_lex.o + ar $(ARFLAGS) $(LIB) dt_lex.o -rm -f dt_lex.o $(BINDIR)/dt_lex.c: dt_lex.l lex -t -v dt_lex.l > $(BINDIR)/dt_lex.c @@ -106,16 +107,16 @@ $(BINDIR)/drti.o: drti.c $(H) $(LIB)(dis_tables.o): ../driver/dis_tables.c $(H) $(CC) $(CPPFLAGS) -Ii386 -I../driver -c ../driver/dis_tables.c - ar rv $(LIB) dis_tables.o + ar $(ARFLAGS) $(LIB) dis_tables.o -rm -f dis_tables.o $(LIB)(dt_names.o): dt_names.c $(CC) $(CPPFLAGS) -c dt_names.c - ar rv $(LIB) dt_names.o + ar $(ARFLAGS) $(LIB) dt_names.o -rm -f dt_names.o $(LIB)(dt_isadep.o): i386/dt_isadep.c $(H) $(CC) $(CPPFLAGS) -Ii386 -I../driver -c i386/dt_isadep.c - ar rv $(LIB) dt_isadep.o + ar $(ARFLAGS) $(LIB) dt_isadep.o -rm -f dt_isadep.o clean: -rm -f dt_errtags.c dt_names.c dt_grammar.h dt_lex.c *.o *.a diff --git a/liblinux/makefile b/liblinux/makefile index fa8c00d..3cf5a13 100644 --- a/liblinux/makefile +++ b/liblinux/makefile @@ -1,3 +1,4 @@ +ARFLAGS=Urv CC=gcc -g $(BUILD_BITS) CPPFLAGS += -I../libproc/common \ -I../common/ctf \ diff --git a/libproc/common/Pgcore.c b/libproc/common/Pgcore.c index 43c7ea2..3d2bc33 100644 --- a/libproc/common/Pgcore.c +++ b/libproc/common/Pgcore.c @@ -83,6 +83,9 @@ typedef struct { shstrtab_t pgc_shstrtab; } pgcore_t; +void bzero(void *, size_t); +void bcopy(const void *src, void *dest, size_t n); + static void shstrtab_init(shstrtab_t *s) { diff --git a/libproc/common/Psymtab.c b/libproc/common/Psymtab.c index f84e46a..9b91e0b 100644 --- a/libproc/common/Psymtab.c +++ b/libproc/common/Psymtab.c @@ -371,6 +371,7 @@ map_iter(const rd_loadobj_t *lop, void *cd) #if defined(linux) fptr->file_lname = strdup((char *) lop->rl_nameaddr); + fptr->file_lbase = basename(fptr->file_lname); /*printf("filename=%s\n", fptr->file_lname);*/ #else if (Pread_string(P, buf, sizeof (buf), lop->rl_nameaddr) > 0) { diff --git a/libproc/common/makefile b/libproc/common/makefile index 2c64df1..369a0e9 100644 --- a/libproc/common/makefile +++ b/libproc/common/makefile @@ -1,3 +1,4 @@ +ARFLAGS=Urv CC=gcc -g $(BUILD_BITS) CPPFLAGS += -I../common \ -I../../common/ctf \ diff --git a/libproc/common/proc_arg.c b/libproc/common/proc_arg.c index b85c8f2..d4758ac 100644 --- a/libproc/common/proc_arg.c +++ b/libproc/common/proc_arg.c @@ -459,7 +459,7 @@ proc_walk(proc_walk_f *func, void *arg, int flag) continue; /* PR_WALK_PROC case */ (void) snprintf(pidstr, sizeof (pidstr), - "%s/%ld/psinfo", procfs_path, pid); + "%s/%ld/psinfo", procfs_path, (long) pid); fd = open(pidstr, O_RDONLY); if (fd < 0) continue; @@ -475,7 +475,7 @@ proc_walk(proc_walk_f *func, void *arg, int flag) } /* PR_WALK_LWP case */ (void) snprintf(pidstr, sizeof (pidstr), - "%s/%ld/lpsinfo", procfs_path, pid); + "%s/%ld/lpsinfo", procfs_path, (long) pid); fd = open(pidstr, O_RDONLY); if (fd < 0) continue; diff --git a/librtld/makefile b/librtld/makefile index 3d3fca4..2fb8e6e 100644 --- a/librtld/makefile +++ b/librtld/makefile @@ -22,13 +22,13 @@ $(LIB): \ $(LIB)(rd_elf32.o): rd_elf.c $(CC) $(CPPFLAGS) -c rd_elf.c mv rd_elf.o rd_elf32.o - ar rv $(LIB) rd_elf32.o + ar $(ARFLAGS) $(LIB) rd_elf32.o rm -f rd_elf32.o $(LIB)(rd_elf64.o): rd_elf.c $(CC) $(CPPFLAGS) -D_ELF64 -c rd_elf.c mv rd_elf.o rd_elf64.o - ar rv $(LIB) rd_elf64.o + ar $(ARFLAGS) $(LIB) rd_elf64.o rm -f rd_elf64.o clean: -rm -f *.o *.a diff --git a/librtld/rtld_db.c b/librtld/rtld_db.c index cb06c21..dd01a27 100644 --- a/librtld/rtld_db.c +++ b/librtld/rtld_db.c @@ -27,6 +27,7 @@ #include +#include #include #include #include @@ -260,7 +261,7 @@ rd_errstr(int rderr) rd_err_e rd_event_addr(rd_agent_t *rdap, rd_event_e event, rd_notify_t *notify) { - printf("proc-stub:%s addr=%p\n", __func__, rdap->rda_addr); + printf("proc-stub:%s addr=%p\n", __func__, (void *) rdap->rda_addr); notify->type = RD_NOTIFY_BPT; notify->u.bptaddr = rdap->rda_addr; diff --git a/linux/sys/signal.h b/linux/sys/signal.h index b8fb2cf..f978c95 100644 --- a/linux/sys/signal.h +++ b/linux/sys/signal.h @@ -69,7 +69,9 @@ #define SIGILL 4 #define SIGTRAP 5 #define SIGABRT 6 +# if !defined(SIGIOT) #define SIGIOT 6 +# endif #define SIGBUS 7 #define SIGFPE 8 #define SIGKILL 9 @@ -95,7 +97,9 @@ #define SIGVTALRM 26 #define SIGPROF 27 #define SIGWINCH 28 +# if !defined(SIGIO) #define SIGIO 29 +# endif #define SIGPOLL SIGIO #define SIGCANCEL 36 /* reserved signal for thread cancellation */ diff --git a/makefile b/makefile index 76829d7..e97c886 100644 --- a/makefile +++ b/makefile @@ -64,7 +64,9 @@ beta: tools/mkrelease.pl -nocopy $$REL all: - BUILD_DIR=$(BUILD_DIR) tools/build.pl $(BUILD_DIR) $(UNAME_M) + BUILD_DIR=$(BUILD_DIR) \ + tools/mkdriver.pl driver-kmem ; \ + tools/build.pl $(BUILD_DIR) $(UNAME_M) cmds: BUILD_DIR=$(BUILD_DIR) tools/build.pl -make do_cmds $(BUILD_DIR) $(UNAME_M) diff --git a/tests/syscalls.c b/tests/syscalls.c index e99bdfe..4e5d8e3 100644 --- a/tests/syscalls.c +++ b/tests/syscalls.c @@ -5,11 +5,25 @@ /* problems. */ /**********************************************************************/ # include +# include # include # include # include # include # include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include /*# include */ static int cnt; @@ -108,8 +122,8 @@ int main(int argc, char **argv) x += getuid(); x += getgid(); x += setsid(); - x += seteuid(); - x += setegid(); + x += seteuid(0); + x += setegid(0); lseek(0, 0, -1); kill(0, 0); signal(99, 0); @@ -118,36 +132,36 @@ int main(int argc, char **argv) // *(int *) 0 = 0; pipe(0); munmap(0, 0); - mincore(0, 0); - shmget(0); - shmat(0); + mincore(0, 0, 0); + shmget(0, 0, 0); + shmat(0, 0, 0); line = __LINE__; - poll(-1, 0, 0); + poll((void *) -1, 0, 0); signal(SIGSEGV, SIG_IGN); // ppoll(-1, -1, -1, 0); signal(SIGSEGV, SIG_DFL); sched_yield(); - readv(-1, 0, 0, 0); - writev(-1, 0, 0, 0); + readv(-1, 0, 0); + writev(-1, 0, 0); msync(0, 0, 0); fsync(-1); fdatasync(-1); semget(0, 0, 0); semctl(0, 0, 0); - uselib(NULL); +// uselib(NULL); pivot_root(0, 0); personality(-1); setfsuid(-1); flock(-1, 0); - shmdt(0, 0, 0); + shmdt(0); times(0); mremap(0, 0, 0, 0, 0); madvise(0, 0, 0); fchown(-1, 0, 0); - lchown(0, 0, 0); - setreuid(); - setregid(); + lchown("", 0, 0); + setreuid(0, 0); + setregid(0, 0); link("/nonexistant", "/also-nonexistant"); do_slow(); @@ -156,11 +170,10 @@ int main(int argc, char **argv) rename("/", "/"); mkdir("/junk/stuff////0", 0777); geteuid(); - getsid(); - getpgid(); + getsid(0); + getpgid(0); getresuid(); getresgid(); - getpgid(); ptrace(-1, 0, 0, 0); semop(0, 0, 0); capget(0, 0); @@ -170,7 +183,7 @@ int main(int argc, char **argv) settimeofday(0, 0); dup(-1); dup2(-1, -1); - shmctl(0, 0, 0, 0); + shmctl(0, 0, 0); execve("/bin/nothing", "/bin/nothing", 0); alarm(9999); bind(0, 0, 0); @@ -199,7 +212,7 @@ int main(int argc, char **argv) sigprocmask(0, 0, 0); x += open("/nothing", 0); x += chdir("/nothing"); - x += mknod("/nothing/nothing", 0); + x += mknod("/nothing/nothing", 0, 0); x += ioctl(); execve("/nothing", NULL, NULL); line = __LINE__; @@ -213,7 +226,7 @@ int main(int argc, char **argv) brk(0); sbrk(0); line = __LINE__; - mmap(0, 0, 0, 0, 0); + mmap(0, 0, 0, 0, 0, 0); line = __LINE__; uname(0); line = __LINE__; @@ -226,7 +239,7 @@ int main(int argc, char **argv) umount(0, 0, 0); swapon(0, 0); swapoff(0); - sethostname(0); + sethostname(0, 0); line = __LINE__; time(NULL); unlink("/nothing"); diff --git a/tools/bug.sh b/tools/bug.sh index 53f51a9..e547963 100755 --- a/tools/bug.sh +++ b/tools/bug.sh @@ -24,18 +24,16 @@ cat <$file 2>&1 +echo "File: $file - send to Crisp.Editor@gmail.com" touch .dtrace.nobug exit 1 diff --git a/tools/build.pl b/tools/build.pl index 3424669..a88854e 100755 --- a/tools/build.pl +++ b/tools/build.pl @@ -92,7 +92,9 @@ sub main # Some precursors to check us out. # ############################################### spawn("tools/check_dep.pl"); - spawn("tools/mkport.pl"); + if (spawn("tools/mkport.pl")) { + die "FATAL ERROR: build.pl aborting\n"; + } spawn("tools/libgcc.pl"); if ($uname_m =~ /x86.*64/) { @@ -174,8 +176,14 @@ sub usage build.pl: dtrace build rule Usage: build.pl \$BUILD_DIR \$UNAME_M + Script to invoke the build. We use 'make' to run build.pl where + all the logic to ensure environment variables, flags, and autodetection + takes place. + Switches: + -help This text. + -i Run 'make -i' so we can carry on even with errors. EOF exit(1); diff --git a/tools/get-deps-fedora.sh b/tools/get-deps-fedora.sh index b6b4718..08204d3 100755 --- a/tools/get-deps-fedora.sh +++ b/tools/get-deps-fedora.sh @@ -14,6 +14,7 @@ yum install \ kernel-devel \ libdwarf \ libdwarf-devel \ + libdwarf-static \ libgcc.i686 \ make \ perl \ diff --git a/tools/get-deps.pl b/tools/get-deps.pl index a5a39bf..ef2d691 100755 --- a/tools/get-deps.pl +++ b/tools/get-deps.pl @@ -16,7 +16,7 @@ if [ ! -e ${DISTRIBUTION} ]; then echo "\n==== Downloading DTrace for Linux ====\n" curl -O -ftp://crisp.dyndns-server.com/pub/release/website/dtrace/${DISTRIBUTION}.tar.bz2 +ftp://crispeditor.co.uk/pub/release/website/dtrace/${DISTRIBUTION}.tar.bz2 tar jxvf ${DISTRIBUTION}.tar.bz2 fi } diff --git a/tools/load.pl b/tools/load.pl index c2fd935..cae7a42 100755 --- a/tools/load.pl +++ b/tools/load.pl @@ -256,6 +256,7 @@ sub main __module_text_address add_timer_on old_rsp:optional + rsp_scratch:optional /) { my $done = 0; my $amd64 = 0; diff --git a/tools/mkdriver.pl b/tools/mkdriver.pl index 6fab12e..9df7146 100755 --- a/tools/mkdriver.pl +++ b/tools/mkdriver.pl @@ -35,7 +35,7 @@ sub main # really need this since all volatile # # stuff is in the build.* dirs anyhow. # ############################################### - if ($cmd eq 'clean') { + if ($cmd && $cmd eq 'clean') { if (!defined($ENV{BUILD_DIR})) { return system("rm -rf build*"); } diff --git a/tools/mkport.pl b/tools/mkport.pl index 3eb2579..0cd8a86 100755 --- a/tools/mkport.pl +++ b/tools/mkport.pl @@ -134,16 +134,31 @@ sub main ############################################### my $old_rsp = `tools/sudo $ENV{BUILD_DIR}/kcore`; chomp($old_rsp); + ############################################### + # 4.2 and above kernels renamed this # + # symbol. # + ############################################### + if (!$old_rsp) { + $old_rsp = get_symbol("rsp_scratch"); + } print "old_rsp=$old_rsp\n"; if ($old_rsp) { $inc .= "# define OLD_RSP_VAL 0x$old_rsp\n"; + } else { + print STDERR <