Message ID | 20201112071411.4202-1-xypron.glpk@gmx.de |
---|---|
State | Changes Requested, archived |
Delegated to: | Simon Glass |
Headers | show |
Series | [1/1] trace: avoid infinite recursion | expand |
Hi Heinrich, >-----Original Message----- >From: Heinrich Schuchardt <xypron.glpk@gmx.de> >Sent: 12 November 2020 12:44 >To: Simon Glass <sjg@chromium.org> >Cc: Pragnesh Patel <pragnesh.patel@openfive.com>; u-boot@lists.denx.de; >Heinrich Schuchardt <xypron.glpk@gmx.de> >Subject: [PATCH 1/1] trace: avoid infinite recursion > >[External Email] Do not click links or attachments unless you recognize the >sender and know the content is safe > >When tracing functions is enabled this adds calls to >__cyg_profile_func_enter() and __cyg_profile_func_exit() to the traced functions. > >__cyg_profile_func_exit() and __cyg_profile_func_exit() invoke Replace one of __cyg_profile_func_exit() with __cyg_profile_func_enter() >timer_get_us() to record the entry and exit time. > >If timer_get_us() or any function used to implement does not carry >__attribute__((no_instrument_function)) this will lead to an indefinite recursion. > >The patch changes __cyg_profile_func_enter() and >__cyg_profile_func_exit() such that during their execution no function is traced >by temporarily setting trace_enabled to false. > >Reported-by: Pragnesh Patel <pragnesh.patel@openfive.com> >Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> >--- > lib/trace.c | 10 ++++++++++ > 1 file changed, 10 insertions(+) > >diff --git a/lib/trace.c b/lib/trace.c >index defc9716d8..b84b9fbfef 100644 >--- a/lib/trace.c >+++ b/lib/trace.c >@@ -141,9 +141,12 @@ static void __attribute__((no_instrument_function)) >add_textbase(void) void __attribute__((no_instrument_function)) >__cyg_profile_func_enter( > void *func_ptr, void *caller) { >+ No need for new line > if (trace_enabled) { > int func; >+ char trace_enabled_old = trace_enabled; > >+ trace_enabled = 0; > trace_swap_gd(); > add_ftrace(func_ptr, caller, FUNCF_ENTRY); > func = func_ptr_to_num(func_ptr); @@ -157,6 +160,7 @@ void >__attribute__((no_instrument_function)) __cyg_profile_func_enter( > if (hdr->depth > hdr->depth_limit) > hdr->max_depth = hdr->depth; > trace_swap_gd(); >+ trace_enabled = trace_enabled_old; > } > } > >@@ -169,11 +173,17 @@ void __attribute__((no_instrument_function)) >__cyg_profile_func_enter( void __attribute__((no_instrument_function)) >__cyg_profile_func_exit( > void *func_ptr, void *caller) { >+ trace_enabled Is this necessary ? >+ > if (trace_enabled) { >+ char trace_enabled_old = trace_enabled; >+ >+ trace_enabled = 0; > trace_swap_gd(); > add_ftrace(func_ptr, caller, FUNCF_EXIT); > hdr->depth--; > trace_swap_gd(); >+ trace_enabled = trace_enabled_old; > } > } > >-- >2.28.0
diff --git a/lib/trace.c b/lib/trace.c index defc9716d8..b84b9fbfef 100644 --- a/lib/trace.c +++ b/lib/trace.c @@ -141,9 +141,12 @@ static void __attribute__((no_instrument_function)) add_textbase(void) void __attribute__((no_instrument_function)) __cyg_profile_func_enter( void *func_ptr, void *caller) { + if (trace_enabled) { int func; + char trace_enabled_old = trace_enabled; + trace_enabled = 0; trace_swap_gd(); add_ftrace(func_ptr, caller, FUNCF_ENTRY); func = func_ptr_to_num(func_ptr); @@ -157,6 +160,7 @@ void __attribute__((no_instrument_function)) __cyg_profile_func_enter( if (hdr->depth > hdr->depth_limit) hdr->max_depth = hdr->depth; trace_swap_gd(); + trace_enabled = trace_enabled_old; } } @@ -169,11 +173,17 @@ void __attribute__((no_instrument_function)) __cyg_profile_func_enter( void __attribute__((no_instrument_function)) __cyg_profile_func_exit( void *func_ptr, void *caller) { + trace_enabled + if (trace_enabled) { + char trace_enabled_old = trace_enabled; + + trace_enabled = 0; trace_swap_gd(); add_ftrace(func_ptr, caller, FUNCF_EXIT); hdr->depth--; trace_swap_gd(); + trace_enabled = trace_enabled_old; } }
When tracing functions is enabled this adds calls to __cyg_profile_func_enter() and __cyg_profile_func_exit() to the traced functions. __cyg_profile_func_exit() and __cyg_profile_func_exit() invoke timer_get_us() to record the entry and exit time. If timer_get_us() or any function used to implement does not carry __attribute__((no_instrument_function)) this will lead to an indefinite recursion. The patch changes __cyg_profile_func_enter() and __cyg_profile_func_exit() such that during their execution no function is traced by temporarily setting trace_enabled to false. Reported-by: Pragnesh Patel <pragnesh.patel@openfive.com> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> --- lib/trace.c | 10 ++++++++++ 1 file changed, 10 insertions(+) -- 2.28.0