Author: Richard Plangger <planri...@gmail.com> Branch: vmprof-native Changeset: r90015:6a9a8962927b Date: 2017-02-09 09:56 +0100 http://bitbucket.org/pypy/pypy/changeset/6a9a8962927b/
Log: add comment for vmprof_execute_code behaviour, extend test which now passes diff --git a/rpython/rlib/rvmprof/rvmprof.py b/rpython/rlib/rvmprof/rvmprof.py --- a/rpython/rlib/rvmprof/rvmprof.py +++ b/rpython/rlib/rvmprof/rvmprof.py @@ -204,11 +204,21 @@ unique_id = get_code_fn(*args)._vmprof_unique_id unique_id = rffi.cast(lltype.Signed, unique_id) # ^^^ removes the "known non-negative" hint for annotation + # + # Signals can occur at the two places (1) and (2), that will + # have added a stack entry, but the function __vmprof_eval_vmprof + # is not entered. This behaviour will swallow one Python stack frame + # + # Current fix: vmprof will discard this sample. those happen + # very infrequent + # if not jit.we_are_jitted(): x = enter_code(unique_id) + # (1) signal here try: return func(*args) finally: + # (2) signal here leave_code(x) else: return decorated_jitted_function(unique_id, *args) diff --git a/rpython/rlib/rvmprof/src/shared/symboltable.c b/rpython/rlib/rvmprof/src/shared/symboltable.c --- a/rpython/rlib/rvmprof/src/shared/symboltable.c +++ b/rpython/rlib/rvmprof/src/shared/symboltable.c @@ -347,7 +347,7 @@ ssize_t count; int version; int flags; - int memory, lines, native; + int memory = 0, lines = 0, native = 0; orig_pos = lseek(fileno, 0, SEEK_CUR); lseek(fileno, 5*WORD_SIZE, SEEK_SET); diff --git a/rpython/rlib/rvmprof/src/shared/vmp_stack.c b/rpython/rlib/rvmprof/src/shared/vmp_stack.c --- a/rpython/rlib/rvmprof/src/shared/vmp_stack.c +++ b/rpython/rlib/rvmprof/src/shared/vmp_stack.c @@ -138,7 +138,7 @@ #endif int vmp_walk_and_record_stack(PY_STACK_FRAME_T *frame, void ** result, - int max_depth, int native_skip, intptr_t pc) { + int max_depth, intptr_t pc) { // called in signal handler #ifdef VMP_SUPPORTS_NATIVE_PROFILING @@ -155,15 +155,17 @@ int ret = unw_init_local(&cursor, &uc); if (ret < 0) { // could not initialize lib unwind cursor and context - return -1; + return 0; } - while (native_skip > 0) { + while (1) { + if (unw_is_signal_frame(&cursor)) { + break; + } int err = unw_step(&cursor); if (err <= 0) { return 0; } - native_skip--; } //printf("stack trace:\n"); @@ -209,31 +211,39 @@ #else { #endif - if (top_most_frame == NULL) { - break; + if (top_most_frame != NULL) { + top_most_frame = _write_python_stack_entry(top_most_frame, result, &depth); + } else { + // Signals can occur at the two places (1) and (2), that will + // have added a stack entry, but the function __vmprof_eval_vmprof + // is not entered. This behaviour will swallow one Python stack frames + // + // (1) PyPy: enter_code happened, but __vmprof_eval_vmprof was not called + // (2) PyPy: __vmprof_eval_vmprof was returned, but exit_code was not called + // + // destroy this sample, as it would display a strage sample + return 0; } - top_most_frame = _write_python_stack_entry(top_most_frame, result, &depth); } } else if (vmp_ignore_ip((intptr_t)func_addr)) { - // this is an instruction pointer that should be ignored, + // this is an instruction pointer that should be ignored // (that is any function name in the mapping range of - // cpython, but of course not extenstions in site-packages)) - //printf("ignoring %s\n", info.dli_sname); + // cpython or libpypy-c.so, but of course not + // extenstions in site-packages) } else { // mark native routines with the first bit set, // this is possible because compiler align to 8 bytes. // - #ifdef PYPY_JIT_CODEMAP if (func_addr == 0 && top_most_frame->kind == VMPROF_JITTED_TAG) { intptr_t pc = ((intptr_t*)(frame->value - sizeof(intptr_t)))[0]; - n = vmprof_write_header_for_jit_addr(result, n, pc, max_depth); + depth = vmprof_write_header_for_jit_addr(result, depth, pc, max_depth); frame = FRAME_STEP(frame); - } else if (func_addr != 0) { + } else if (func_addr != 0x0) { depth = _write_native_stack((void*)(func_addr | 0x1), result, depth); } #else - if (func_addr != 0) { + if (func_addr != 0x0) { depth = _write_native_stack((void*)(func_addr | 0x1), result, depth); } #endif @@ -241,8 +251,10 @@ int err = unw_step(&cursor); if (err == 0) { + //printf("sample ended\n"); break; } else if (err < 0) { + //printf("sample is broken\n"); return 0; // this sample is broken, cannot walk it fully } } diff --git a/rpython/rlib/rvmprof/src/shared/vmp_stack.h b/rpython/rlib/rvmprof/src/shared/vmp_stack.h --- a/rpython/rlib/rvmprof/src/shared/vmp_stack.h +++ b/rpython/rlib/rvmprof/src/shared/vmp_stack.h @@ -3,7 +3,7 @@ #include "vmprof.h" int vmp_walk_and_record_stack(PY_STACK_FRAME_T * frame, void **data, - int max_depth, int native_skip, intptr_t pc); + int max_depth, intptr_t pc); int vmp_native_enabled(void); int vmp_native_enable(void); diff --git a/rpython/rlib/rvmprof/src/shared/vmprof_main.h b/rpython/rlib/rvmprof/src/shared/vmprof_main.h --- a/rpython/rlib/rvmprof/src/shared/vmprof_main.h +++ b/rpython/rlib/rvmprof/src/shared/vmprof_main.h @@ -101,15 +101,7 @@ } frame = current->frame; #endif - // skip over - // _sigtramp - // sigprof_handler - // vmp_walk_and_record_stack -#ifdef __unix__ - return vmp_walk_and_record_stack(frame, result, max_depth, 4, pc); -#else - return vmp_walk_and_record_stack(frame, result, max_depth, 3, pc); -#endif + return vmp_walk_and_record_stack(frame, result, max_depth, pc); } /* ************************************************************* diff --git a/rpython/rlib/rvmprof/test/test_rvmprof.py b/rpython/rlib/rvmprof/test/test_rvmprof.py --- a/rpython/rlib/rvmprof/test/test_rvmprof.py +++ b/rpython/rlib/rvmprof/test/test_rvmprof.py @@ -151,7 +151,7 @@ from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.rtyper.lltypesystem import rffi, lltype def test_native(): - eci = ExternalCompilationInfo(compile_extra=['-g','-O2'], + eci = ExternalCompilationInfo(compile_extra=['-g','-O1'], separate_module_sources=[""" RPY_EXTERN int native_func(void) { int j = 0; @@ -209,10 +209,24 @@ tree = prof.get_tree() p = PrettyPrinter() p._print_tree(tree) - assert tree.name.startswith("n:pypy_g_main") + def walk(tree, symbols): + symbols.append(tree.name) + if len(tree.children) == 0: + return + assert len(tree.children) == 1 + for child in tree.children.values(): + walk(child, symbols) + symbols = [] + walk(tree, symbols) + not_found = ['n:pypy_g_main', 'n:native_func', 'n:pypy_g_f', + 'n:pypy_g_main'] + for sym in symbols: + for i,name in enumerate(not_found): + if sym.startswith(name): + del not_found[i] + break + assert not_found == [] - #assert f() == 0 - #assert os.path.exists(tmpfilename) fn = compile(f, [], gcpolicy="minimark") assert fn() == 0 try: _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit