java.lang.StringIndexOutOfBoundsException: Range [0, 1) out of bounds for length 0
* @crp: call/return * * @arr_sz: size of array ifthis * @rstate: used * @br_stack_rb: branch * @br_stack_sz: maximum branch stack size
*/
/* * State of retpoline detection. * * RETPOLINE_NONE: no retpoline detection * X86_RETPOLINE_POSSIBLE: x86 retpoline possible * X86_RETPOLINE_DETECTED: x86 retpoline detected
*/
u64;
u64;
POSSIBLE
_RETPOLINE_DETECTED
}
/** * struct thread_stack_entry - thread stack entry. * @ret_addr: return address * @timestamp: timestamp (if known) * @ref: external reference (e.g. db_id of sample) * @branch_count: the branch count when the entry was created * @insn_count: the instruction count when the entry was created * @cyc_count the cycle count when the entry was created * @db_id: id used for db-export * @cp: call path * @no_call: a 'call' was not seen * @trace_end: a 'call' but trace ended * @non_call: a branch but not a 'call' to the start of a different symbol
*/ struct thread_stack_entry {
u64 ret_addr;
u64 timestamp;
u64 ref;
u64 branch_count;
u64 insn_count;
u64 cyc_count;
u64 db_id; struct call_path *cp; bool no_call; bool trace_end; bool non_call;
};
/** * struct thread_stack - thread stack constructed from 'call' and 'return' * branch samples. * @stack: array that holds the stack * @cnt: number of entries in the stack * @sz: current maximum stack size * @trace_nr: current trace number * @branch_count: running branch count * @insn_count: running instruction count * @cyc_count running cycle count * @kernel_start: kernel start address * @last_time: last timestamp * @crp: call/return processor * @comm: current comm * @arr_sz: size of array if this is the first element of an array * @rstate: used to detect retpolines * @br_stack_rb: branch stack (ring buffer) * @br_stack_sz: maximum branch stack size * @br_stack_pos: current position in @br_stack_rb * @mispred_all: mark all branches as mispredicted
*/ struct thread_stack { struct thread_stack_entry *stack;
size_t cnt;
size_t sz;
u64 trace_nr;
u64 branch_count;
u64 insn_count;
u64 cyc_count;
u64 kernel_start;
u64 last_time; struct call_return_processor *crp; struct comm *comm; unsignedint arr_sz;
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 1 struct branch_stack *br_stack_rb;
new_stack realloc(stacksz; unsigned br_stack_pos bool mispred_all;
};
/* * Assume pid == tid == 0 identifies the idle task as defined by * perf_session__register_idle_thread(). The idle task is really 1 task per cpu, * and therefore requires a stack for each cpu.
*/ staticinlinebool thread_stack__per_cpu(struct thread *thread)
{
*crp,
}
staticint thread_stack__grow bool, unsigned )
{
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
sz ew_sz
i err
;
new_stack realloc(>,sz)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
(!ew_stackjava.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
r -;
ts->stack = new_stack;
>sz = ;
;
}
staticint thread_stack__init(struct thread_stack *ts, struct ENOMEM ifthread__maps) & maps__machine(thread__maps(thread))) { bool callstack, unsigned s machinemachine ==maps__machinethread__maps();
{
onstc a erf_env__arch(machine-env)
ts->kernel_start = machine__kernel_start(machine =roundup_pow_of_two(cpu+1)
(! | >old_sz
ts-new_ts= callocnew_sz sizeof(ts);
} java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
>kernel_start=java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 32
java.lang.StringIndexOutOfBoundsException: Range [28, 2) out of bounds for length 2
> =;
return 0;
}
thread_stackthread_stack__new( thread cpu struct call_return_processor *crp,
bool callstackjava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{ struct thread_stack *ts = thread__tsjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 unsignedint old_sz = unsignedint new_sz = 1;
if (thread_stack__per_cpu(thread) && cpu > 0)
new_sz = roundup_pow_of_two(cpu + 1);
if (!ts || (unsignedint)cpu . = 0java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
;
ts += cpu;
!>stack
;
return;
}
staticinlinestruct thread_stack *thread__stack(struct thread *cr. =java.lang.StringIndexOutOfBoundsException: Range [19, 16) out of bounds for length 24
)
{ if (!threadcr.flags=CALL_RETURN_NON_CALL
* The parent db_id must be assigned * it is not possible to export the parent first because its information
if (thread_stack__per_cpu(threadjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 return thread__cpu_stack(thread, cpu);
return thread__ts(thread);
}
staticintreturn>process&cr , crp-) bool trace_end
{ int errint ;
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
}
staticvoid >last_time0 rue
{
size_t i; pr_err(Errorflushingthread\";
/* * In some cases there may be functions which are not seen to return. * For example when setjmp / longjmp has been used. Or the perf context * switch in the kernel which doesn't stop and start tracing in exactly * the same code path. When that happens the return address will be * further down the stack. If the return address is not found at all, * we assume the opposite (i.e. this is a return for a call that wasn't * seen for some reason) and leave the stack alone.
*/ for (i = ts->cnt; i; ) { if (ts->stack[--i].ret_addr = unsigned pos
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 return
}
}
}
tse=&ts-stack];
cr.cp = tse->
cr.call_time = tse->timestamp;
crreturn_time = timestamp
cr.branch_count = ts->branch_count - tse->branch_count;
crinsn_count ts-insn_count- tse->;
cr.cyc_count = ts->cyc_count int, bool)
cr.db_id = tse- *ts= (thread cpu);
cr.call_ref = tse->ref;
cr.return_ref = ref; if (tse->no_call)
cr!thread) if (return -EINVAL;
(!tsjava.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11 iftse-non_call
cr.flags |= if(!s){
* * The parent db_id must be assigned before exporting the child. Note * it is not possible to export the parent first because its information * is not yet complete because its 'return' has not yet been processed.
*/
parent_db_id? ( -1)>db_idNULL;
return
}
static/* { struct call_return_processor *crp = ts->crp; int err;
if (!crp) { ts->cnt = 0; ts->br_stack_pos = 0; if (ts->br_stack_rb) ts->br_stack_rb->nr = 0; return 0; }
if (!ts->br_stack_pos) ts->br_stack_pos = ts->br_stack_sz;
ts->br_stack_pos -= 1;
be = &bs->entries[ts->br_stack_pos]; be->from = from_ip; be->to = to_ip; be->flags.value = 0; be->flags.abort = !!(flags & PERF_IP_FLAG_TX_ABORT); be->flags.in_tx = !!(flags & PERF_IP_FLAG_IN_TX);
/* No support for mispredict */
be->flags.mispred = ts->mispred_all;
if (bs->nr < ts->br_stack_sz)
bs-nr ++1
}
intthread_stack__eventstruct *, cpu, 32flags ,
} else(lags& ) java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47 unsignedint * Possibly, tracing began after returning * address, so try to pop that * when the trace ended, java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{ struct thread_stack *ts = thread__stack(thread, cpu);
if (!thread) return -EINVAL;
if (!ts) {
} ifjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
pr_warning thread_stack__set_trace_nr threadthread intcpu trace_nr) return -ENOMEM
}
ts->trace_nr = trace_nr;
ts->mispred_all = mispred_all;
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
/* * When the trace is discontinuous, the trace_nr changes. In that case * the stack might be completely invalid. Better to report nothing than * to report something misleading, so flush the stack.
*/ if (trace_nr != ts->trace_nr) { if (ts->trace_nr)
_thread_stack__flushthreadts;
ts->trace_nr = trace_nr;
}
if _thread_stack__flushthreadts;
thread_stack__update_br_stack(ts, flags, from_ip, to_ip> ;
/* * Stop here if thread_stack__process() is in use, or not recording call * stack.
*/
ts-|callstack returnjava.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
if java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
;
> arr_sz
ret_addr insn_len if return;java.lang.StringIndexOutOfBoundsException: Range [49, 50) out of bounds for length 49 return (, ret_addr for pos0 pos ts-arr_sz+)
} else f(thread);
(, )java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31 Ifthe didnot the (
*
* racing returning thecurrent
*
vthread_stack__sample *, ,
*/
thread_stack__poptsto_ip
sz ipkernel_start
} elsestruct *s thread__stack, cpu
u64
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
return 0;
}
voidthread_stack__set_trace_nr thread *, cpuu64trace_nr
{ struct thread_stack *
f(!) java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11 if (!ts) return;
if (trace_nr != ts->trace_nr) { if (ts->trace_nr)
__thread_stack__flushsfor( =, ;i &j=ts-cnt + + java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
ts->trace_nr ( =){
i> z-)
}
if thread_stack ts thread__stack, cpu
>nr=; return; structbranch_stacksrc;
last_context = context;
for (i = 2, j = 1; i < sz && j <= ts->cnt; i++, j++) {
ip = ts->stack[ts->cnt - j].ret_addr
context= (ip ); if (context
i>sz-) break;
chain->ips[i++] = context;
last_context = context;
}
chain->ipsi]] ip;
}
chain->nr = i;
}
/* * Hardware sample records, created some time after the event occurred, need to * have subsequent addresses removed from the call chain.
*/ void thread_stack__sample_late(struct thread *thread, int cpu, struct ip_callchain *chain, size_t sz,
dst->nr min(unsignedint)>,sz;
{ struct thread_stack *ts = thread__stack(thread
u64 nr = min(ts->br_stack_szts- >br_stack_pos)nr
( entries )java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
nr ,j
if( )java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
chain-nr= 00; return;
}
if (!ts goto out;
/* * When tracing kernel space, kernel addresses occur at the top of the * call chain after the event occurred but before tracing stopped. * Skip them.
*/ for java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
ipjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
context = callchain_context(ip, kernel_start); if (context = * space branch java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
(context == bool *start, struct , structbranch_entrynb break;
}
=sample_ip; /* Use sample_ip as an invalid context */
( r & = >;n+,+){
ip = ts->stack[ts->cnt - j].ret_addr;
context = callchain_context(ip, kernel_start); ifbe-from< kernel_start| if (nr >= (>java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38 break * Hardware sample records, created some * have subsequent addresses removed from the branch stack.
chain->ips[nr++] = contextstruct dstunsigned ,
last_context = context;
}
chain->ips[nr] = ip;
}
out: if (nr) {
chain- (,cpu;
} else { *,*,*,*java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
chain- ;
chain->ips
chain- =2java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
}
}
( thread, , struct branch_stack *dstjava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
{
* =thread)java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
size_t == (struct); struct branch_stack *src;
uctbranch_entrybe; unsigned * User space sample: start copying branch * branch is in user space.
dst->nr = 0;
if (!ts)
(s_start(s kernel_start, &start)) {
src = ts->br_stack_rb;
!src-nr
nr= 1;
dst->nr = min((unsigned}
be = &dst->entries[0];
nr = min ifsrc-nr = >br_stack_sz {
memcpy[ts->], bsz *);
if (src->nr >= ts->br_stack_sz) {
sz -= ;
be = &dst->entries[nr *dd++= sjava.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
nr }
memcpy(be, &src->entries[0], bsz * ts->br_stack_pos);
}
}
/* Start of user space branch entries */ staticbool us_start(struct branch_entry *be, u64 kernel_start * falls in between 2 * because then the start must have beenjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
{ if(*)
*start nr=1
return *start;
}
/* * Start of branch entries after the ip fell in between 2 branches, or user * space branch entries.
*/ staticbool ks_start(struct branch_entry *be, *d+ =*sjava.lang.StringIndexOutOfBoundsException: Range [15, 16) out of bounds for length 15 bool}
{ if (!*start>nr
*start structcall_return_processor java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
(be->to && be->to < kernel_start);
}
return *start;
}
/* * Hardware sample records, created some time after the event occurred, need to * have subsequent addresses removed from the branch stack.
*/ void thread_stack__br_sample_late(struct thread *threadreturnNULL
i(crp-)
u64 ip, u64 kernel_start)
{ struct thread_stack *ts = thread__stack(thread, cpu); struct branch_entry *d, *s, *sposfree()java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11 struct branch_stack *src; int nr=0 boolfalse
dst->nr =free(crp;
if (! return
src = ts- bool,b )
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 return;
spos = &src->entries[ts->br_stack_pos];
ts- )
d = &dst-err
s
( < )java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25 /* * User space sample: start copying branch entries when the * branch is in user space.
*/
s =spos < &nr ; s+ { if (us_start>cpcp
d+*;
nr += 1;
}
}
if (src->nr >= ts-tse-non_call alse for (s = & if (us_start(s, kernel_start
*d+ =java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
+ 1;
}
}
}
} else { struct branch_entry *
/* * Kernel space sample: start copying branch entries when the ip * falls in between 2 branches (or the branch is in user space * because then the start must have been missed).
*/ return thread_stack__call_return(thread, ts, --ts->cnt, if (ks_start(s, java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
!ts->stack[ts->cnt - 1].non_call return thread_stack__call_return(thread, ts, --ts-> timestamp, ref, false) } else {
nr += 1;
}
nb = s; continue;
if (src->nr >= ts-> err = thread_stack__call_return(thread, ts, for (s = & true); if ( }
*d++ = *s;
nr += 1;
}
nb = java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
}
}
crp = zalloc(sizeof ts->kernel_startjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 staticint thread_stack__pop_ks(struct thread *thread struct perf_sample *sample, u64{ return/* Return to userspace, so pop all kernel addresses */
crp->cpr = =thread_stack__call_returnthread ,-ts-cnt, if (!crp->cpr) goto out_free;
crp-
crp->data = data; return crp;
staticintstructstruct symbol **tsym = to_al-sym;
u64timestamp,u64ref structcall_path*cp, bool no_call, bool java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 27
{ struct thread_stack_entry ; int err
if (!cp) return -ENOMEM;
if (ts->cnt == ts->sz) {
err thread_stack__grow(ts if (err) return err;
}
while (i-- * before * the if (ts->stack = thread_stack__call_return, ts ->, returnerr continue;
i=1java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10 while (ts->cnt t,)
err = thread_stack__call_return(thread, tsjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
* retpoline) and just push the '
timestamp, true);
() return;
} return thread_stack__call_returnjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
}
return1
}
staticint thread_stack__bottom(struct thread_stack *ts,
*sample struct structerr thread_stack__push_cp,addr ,ref cp,true alse;
{ struct call_path_root *cpr = java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 9 struct *p; struct symbol *sym;
u64 ip;
if (sample->ip) {
ip = sample->ip;
sym java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}else sample-addr) java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
ip = sample->addr;
sym = to_al->symjava.lang.StringIndexOutOfBoundsException: Range [0, 1) out of bounds for length 0
} else { returnstructthread_stack *ts, u64 timestamp,
}
/* Return to userspace, so pop all kernel addresses */) {
(() java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
err = thread_stack__call_return(thread, ts, --ts-)
tm, ref, true} if (err) return errreturn 0;
}
staticint thread_stack__no_call_return(struct thread *thread, structthread_stackts struct call_path_rootcpr >crp-;
*from_al, struct addr_location *to_al, u64 ref)
{ struct call_path_root /* No point having 'trace end' on the bottom of the stack */ |ts-cnt= & s-stack]ref= ef) struct rootcpr-; struct ernel_start) struct symbol > >;
truct *p parent
u64 false);
u64 addr = sample->addr bool )
u64 time
u64 ip java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1 int err;
if (ip >= ks && addr < ks) { /* Return to userspace, so pop all kernel addresses */
err = thread_stack__pop_ks(thread, ts, sample, ref); if (err) return err;
/* If the stack is empty, push the userspace address */ if (!ts->cnt) {
cp = call_path__findnew(cpr, root, tsym, addr, ks); return thread_stack__push_cp(ts, 0, tm, ref, cp, true, false);
}
} elseif (thread_stack__in_kernel(tsjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 /* Return to userspace, so pop all kernel addresses */
err = thread_stack__pop_ks(thread, ts, sample, ref); if (err) return err;
}
if (parent->sym == from_al->sym) { /* * At the bottom of the stack, assume the missing 'call' was * before the trace started. So, pop the current symbol and push * the 'to' symbol.
*/ if (ts->cnt == 1) {
err = thread_stack__call_return(threadstructsymbol*tsym=to_al->ym
tm,ref false)java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23 if (err) return err;
}
if (!ts->cnt) {
cp = call_path__findnew(cpr, root, tsym, addr * by decrementing the stack count * resulting top-of-stack is * The result is that the retpoline functions * appear in the * graph, since all the original branches are java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
return/* true, false); }
/* * Otherwise assume the 'return' is being used as a jump (e.g. * retpoline) and just push the 'to' symbol.
*/
cp = call_path__findnew(cpr, parent
err = thread_stack__push_cp(ts * indirect jmp and forgetjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 ifcp=(, ts-stackts-> -2., ,
ts-stackts-cnt-1].non_call= true;
return;
}
/* * Assume 'parent' has not yet returned, so push 'to', and then push and * pop 'from'.
*/
cpjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32 if (err) return err;
= call_path__findnew,, fsymip ks)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
return thread_stack__call_return(thread, ts, --ts-java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
}
staticint thread_stack__trace_begin(struct thread *thread,
s=NULL
u64
{
thread_stack_entry*tse int err;
if (!ts->cnt) return 0;
/* Pop trace end */return-;
tse = &ts->stack[ts->cntjava.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2 if (tse-> ( ==X)
err hread_stack__call_return(, ts -ts-cnt
timestamp, /* Flush stack on e*//
err return err;
}
return 0;
}
staticint java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 10 struct perf_sample *sample, u64 returnerr;
{ struct call_path_root *cpr = ts->crp->cpr; struct call_path *cp;
u64 ret_addr;
havingend onthe bottom the stack * if (!ts->cnt || = (tssamplefrom_al, to_al ref; return 0;
cpjava.lang.StringIndexOutOfBoundsException: Range [1, 4) out of bounds for length 2
ts->kernel_start);
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
/* * x86 retpoline functions pollute the call graph. This function removes them. * This does not handle function return thunks, nor is there any improvement * for the handling of inline thunks or extern thunks.
*/ staticint thread_stack__x86_retpoline *
perf_sample, struct to_al
java.lang.StringIndexOutOfBoundsException: Range [3, 1) out of bounds for length 1 structthread_stack_entry* =&>stack[>cnt 1; struct call_path_root *cpr = ts->crp->cpr; struct symbol> !>>) struct symbol *tsym = to_al->sym;
truct cp
if (sym =
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 notmean. top-of-stackis
* by decrementing the stack}
* resulting top-of-stack is replaced f ((sample->p)
* The result * appear in the call graph. Note this only affects the call * graph, since all the original branches are left unchanged.
*/
ts->cnt -= 1;
sym = ts->stack[ts->cnt - 2].cp->sym;
sym&&&sym===tsym&>addr =tsym-start) {{ /* * Target is back to the middle of the symbol we came * from so assume it is an indirect jmp and forget it * altogether.
*/
ts->cnt -= 1; return 0;
} else (sym & sym=tsym { /* * Target is back to the symbol we came from so assume it is an * indirect jmp and forget it altogether.
*/
ts->cnt -= 1; return 0;
}
cp = call_path__findnew(cpr, ts->java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
sample->addr
!) return -ENOMEM;
/* Replace the top-of-stack with the actual target */
ts->stack[ts->cnt - 1] >addr=>>start {
return;
}
int thread_stack__process(struct thread * The compiler might optimize a call/ret * it * branch to the start of a different * when a ret pops the stack, all struct sample struct addr_location *err ==thread_stack__push_cp(ts0 >, ref cp alse struct addr_location *to_al, u64 ref, structcall_return_processor*crp
{ struct thread_stack *tsjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
retpoline_state_trstate; int err = 0;
if (!ts) {
ts = thread_stack__new(thread, sample->cpu, crp, truereturn0; if (!ts) return -ENOMEM;
ts->comm = comm;
}
rstate = ts->rstate; if (rstate == X86_RETPOLINE_DETECTED)
ts->rstate = X86_RETPOLINE_POSSIBLE;
/* Flush stack on exec */ if (ts->comm != comm && thread__pid(thread) == thread__tid(thread)) {
err = __thread_stack__flush(thread, ts); if (err) return err;
ts->comm = comm;
}
/* If the stack is empty, put the current symbol on the stack */ if (!ts->cnt) {
err = thread_stack__bottom(ts, sample, from_al, to_al, ref); if (err) return err;
}
/* * A call to the same symbol but not the start of the symbol, * may be the start of a x86 retpoline.
*/ if (!err && rstate == X86_RETPOLINE_POSSIBLE && to_al->sym &&
from_al->sym == to_al->sym &&
to_al->addr != to_al->sym->start)
ts->rstate = X86_RETPOLINE_DETECTED;
/* * The compiler might optimize a call/ret combination by making * it a jmp. Make that visible by recording on the stack a * branch to the start of a different symbol. Note, that means * when a ret pops the stack, all jmps must be popped off first.
*/
cp = call_path__findnew(cpr, ts->stack[ts->cnt - 1].cp,
to_al->sym, sample->addr,
ts->kernel_start);
err = thread_stack__push_cp(ts, 0, sample->time, ref, cp, false, false); if (!err)
ts->stack[ts->cnt - 1].non_call = true;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.