Author: Richard Plangger <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit