Author: fijal Branch: windows-vmprof-support Changeset: r82175:4ff8e1c7f441 Date: 2016-02-12 12:42 +0100 http://bitbucket.org/pypy/pypy/changeset/4ff8e1c7f441/
Log: an attempt to finalize windows diff --git a/rpython/rlib/rvmprof/cintf.py b/rpython/rlib/rvmprof/cintf.py --- a/rpython/rlib/rvmprof/cintf.py +++ b/rpython/rlib/rvmprof/cintf.py @@ -89,11 +89,9 @@ s.c_next = vmprof_tl_stack.get_or_make_raw() s.c_value = unique_id s.c_kind = VMPROF_CODE_TAG - print s vmprof_tl_stack.setraw(s) return s def leave_code(s): vmprof_tl_stack.setraw(s.c_next) - print "pop" lltype.free(s, flavor='raw') diff --git a/rpython/rlib/rvmprof/src/vmprof_common.h b/rpython/rlib/rvmprof/src/vmprof_common.h --- a/rpython/rlib/rvmprof/src/vmprof_common.h +++ b/rpython/rlib/rvmprof/src/vmprof_common.h @@ -71,6 +71,43 @@ return _write_all((char*)&header, 5 * sizeof(long) + 4 + namelen); } +/* ************************************************************* + * functions to dump the stack trace + * ************************************************************* + */ + + +static int get_stack_trace(vmprof_stack_t* stack, intptr_t *result, int max_depth, intptr_t pc) +{ + int n = 0; + intptr_t addr = 0; + int bottom_jitted = 0; + // check if the pc is in JIT +#ifdef PYPY_JIT_CODEMAP + if (pypy_find_codemap_at_addr((intptr_t)pc, &addr)) { + // the bottom part is jitted, means we can fill up the first part + // from the JIT + n = vmprof_write_header_for_jit_addr(result, n, pc, max_depth); + stack = stack->next; // skip the first item as it contains garbage + } +#endif + while (n < max_depth - 1 && stack) { + if (stack->kind == VMPROF_CODE_TAG) { + result[n] = stack->kind; + result[n + 1] = stack->value; + n += 2; + } +#ifdef PYPY_JIT_CODEMAP + else if (stack->kind == VMPROF_JITTED_TAG) { + pc = ((intptr_t*)(stack->value - sizeof(intptr_t)))[0]; + n = vmprof_write_header_for_jit_addr(result, n, pc, max_depth); + } +#endif + stack = stack->next; + } + return n; +} + #ifndef RPYTHON_LL2CTYPES static vmprof_stack_t *get_vmprof_stack(void) { diff --git a/rpython/rlib/rvmprof/src/vmprof_main.h b/rpython/rlib/rvmprof/src/vmprof_main.h --- a/rpython/rlib/rvmprof/src/vmprof_main.h +++ b/rpython/rlib/rvmprof/src/vmprof_main.h @@ -80,43 +80,6 @@ #include "vmprof_get_custom_offset.h" -/* ************************************************************* - * functions to dump the stack trace - * ************************************************************* - */ - - -static int get_stack_trace(intptr_t *result, int max_depth, intptr_t pc, ucontext_t *ucontext) -{ - vmprof_stack_t* stack = get_vmprof_stack(); - int n = 0; - intptr_t addr = 0; - int bottom_jitted = 0; - // check if the pc is in JIT -#ifdef PYPY_JIT_CODEMAP - if (pypy_find_codemap_at_addr((intptr_t)pc, &addr)) { - // the bottom part is jitted, means we can fill up the first part - // from the JIT - n = vmprof_write_header_for_jit_addr(result, n, pc, max_depth); - stack = stack->next; // skip the first item as it contains garbage - } -#endif - while (n < max_depth - 1 && stack) { - if (stack->kind == VMPROF_CODE_TAG) { - result[n] = stack->kind; - result[n + 1] = stack->value; - n += 2; - } -#ifdef PYPY_JIT_CODEMAP - else if (stack->kind == VMPROF_JITTED_TAG) { - pc = ((intptr_t*)(stack->value - sizeof(intptr_t)))[0]; - n = vmprof_write_header_for_jit_addr(result, n, pc, max_depth); - } -#endif - stack = stack->next; - } - return n; -} static intptr_t get_current_thread_id(void) { @@ -194,8 +157,8 @@ struct prof_stacktrace_s *st = (struct prof_stacktrace_s *)p->data; st->marker = MARKER_STACKTRACE; st->count = 1; - depth = get_stack_trace(st->stack, - MAX_STACK_DEPTH-2, GetPC((ucontext_t*)ucontext), ucontext); + depth = get_stack_trace(get_vmprof_stack(), st->stack, + MAX_STACK_DEPTH-2, GetPC((ucontext_t*)ucontext)); st->depth = depth; st->stack[depth++] = get_current_thread_id(); p->data_offset = offsetof(struct prof_stacktrace_s, marker); diff --git a/rpython/rlib/rvmprof/src/vmprof_main_win32.h b/rpython/rlib/rvmprof/src/vmprof_main_win32.h --- a/rpython/rlib/rvmprof/src/vmprof_main_win32.h +++ b/rpython/rlib/rvmprof/src/vmprof_main_win32.h @@ -71,82 +71,72 @@ return 0; } -int vmprof_snapshot_thread(prof_stacktrace_s *stack) +int vmprof_snapshot_thread(struct pypy_threadlocal_s *p, prof_stacktrace_s *stack) { - void *addr; - vmprof_stack_t *cur; - long tid; - HANDLE hThread; + void *addr; + vmprof_stack_t *cur; + long tid; + HANDLE hThread; + long depth; + DWORD result; + CONTEXT ctx; #ifdef RPYTHON_LL2CTYPES - return 0; // not much we can do + return 0; // not much we can do #else - OP_THREADLOCALREF_ADDR(addr); -#ifdef RPY_TLOFS_thread_ident // compiled with threads - tid = *(long*)((char*)addr + RPY_TLOFS_thread_ident); - hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, tid); - if (!hThread) { - return -1; - } - result = SuspendThread(hThread); - if(result == 0xffffffff) - return -1; // possible, e.g. attached debugger or thread alread suspended - if (*(long*)((char*)addr + RPY_TLOFS_thread_ident) != tid) { - // swapped threads, bail - ResumeThread(hThread); - return -1; - } -#endif - cur = *(vmprof_stack_t**)((char*)addr + RPY_TLOFS_vmprof_tl_stack); - if (cur) { - printf("%p\n", cur->kind); - } else { - printf("null\n"); - } -#ifdef RPY_TLOFS_thread_ident - ResumeThread(hThread); -#endif - /* HRESULT result; - HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, thread_id); - int depth; +#ifndef RPY_TLOFS_thread_ident + return 0; // we can't freeze threads, unsafe +#else + hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, p->thread_ident); if (!hThread) { return -1; } result = SuspendThread(hThread); if(result == 0xffffffff) return -1; // possible, e.g. attached debugger or thread alread suspended - // find the correct thread - depth = read_trace_from_cpy_frame(tstate->frame, stack->stack, - MAX_STACK_DEPTH); + ctx.ContextFlags = CONTEXT_FULL; + if (!GetThreadContext(hThread, &ctx)) + return -1; + depth = get_stack_trace(p->vmprof_tl_stack, + stack->stack, MAX_STACK_DEPTH-2, ctx.Eip); stack->depth = depth; - stack->stack[depth++] = (void*)thread_id; + stack->stack[depth++] = (void*)p->thread_ident; stack->count = 1; stack->marker = MARKER_STACKTRACE; ResumeThread(hThread); - return depth;*/ - return 0; + return depth; +#endif #endif } long __stdcall vmprof_mainloop(void *arg) { + struct pypy_threadlocal_s *p; prof_stacktrace_s *stack = (prof_stacktrace_s*)malloc(SINGLE_BUF_SIZE); - HANDLE hThreadSnap = INVALID_HANDLE_VALUE; int depth; while (1) { - //Sleep(profile_interval_usec * 1000); - Sleep(10); + //Sleep(profile_interval_usec * 1000); + Sleep(10); if (!enabled) { continue; } - depth = vmprof_snapshot_thread(stack); - if (depth > 0) { - _write_all((char*)stack + offsetof(prof_stacktrace_s, marker), - depth * sizeof(void *) + - sizeof(struct prof_stacktrace_s) - - offsetof(struct prof_stacktrace_s, marker)); + _RPython_ThreadLocals_Acquire(); + p = _RPython_ThreadLocals_Head(); // the first one is one behind head + p = _RPython_ThreadLocals_Enum(p); + while (p) { + if (p->ready == 42) { + depth = vmprof_snapshot_thread(p, stack); + if (depth > 0) { + _write_all((char*)stack + offsetof(prof_stacktrace_s, marker), + depth * sizeof(void *) + + sizeof(struct prof_stacktrace_s) - + offsetof(struct prof_stacktrace_s, marker)); + } + } + p = _RPython_ThreadLocals_Enum(p); } + _RPython_ThreadLocals_Release(); } } diff --git a/rpython/rlib/rvmprof/test/test_ztranslation.py b/rpython/rlib/rvmprof/test/test_ztranslation.py --- a/rpython/rlib/rvmprof/test/test_ztranslation.py +++ b/rpython/rlib/rvmprof/test/test_ztranslation.py @@ -3,11 +3,10 @@ sys.path += ['../../../..'] # for subprocess in test_interpreted import py from rpython.tool.udir import udir -from rpython.rlib import rvmprof +from rpython.rlib import rvmprof, rthread from rpython.translator.c.test.test_genc import compile from rpython.rlib.nonconst import NonConstant - class MyCode: def __init__(self, count): self.count = count @@ -39,6 +38,7 @@ PROF_FILE = str(udir.join('test_ztranslation.prof')) def main(argv=[]): + rthread.get_ident() # force TLOFS_thread_ident if NonConstant(False): # Hack to give os.open() the correct annotation os.open('foo', 1, 1) diff --git a/rpython/translator/c/src/threadlocal.c b/rpython/translator/c/src/threadlocal.c --- a/rpython/translator/c/src/threadlocal.c +++ b/rpython/translator/c/src/threadlocal.c @@ -85,6 +85,11 @@ return prev->next; } +struct pypy_threadlocal_s *_RPython_ThreadLocals_Head(void) +{ + return &linkedlist_head; +} + static void _RPy_ThreadLocals_Init(void *p) { struct pypy_threadlocal_s *tls = (struct pypy_threadlocal_s *)p; diff --git a/rpython/translator/c/src/threadlocal.h b/rpython/translator/c/src/threadlocal.h --- a/rpython/translator/c/src/threadlocal.h +++ b/rpython/translator/c/src/threadlocal.h @@ -27,6 +27,9 @@ RPY_EXTERN struct pypy_threadlocal_s * _RPython_ThreadLocals_Enum(struct pypy_threadlocal_s *prev); +/* will return the head of the list */ +RPY_EXTERN struct pypy_threadlocal_s *_RPython_ThreadLocals_Head(); + #define OP_THREADLOCALREF_ACQUIRE(r) _RPython_ThreadLocals_Acquire() #define OP_THREADLOCALREF_RELEASE(r) _RPython_ThreadLocals_Release() #define OP_THREADLOCALREF_ENUM(p, r) r = _RPython_ThreadLocals_Enum(p) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit