@@ -430,9 +430,10 @@ RTM_EXPORT(rt_kprintf);
430430 */
431431rt_weak rt_err_t rt_backtrace (void )
432432{
433- struct rt_hw_backtrace_frame frame ;
433+ struct rt_hw_backtrace_frame frame = { 0 } ;
434434 rt_thread_t thread = rt_thread_self ();
435435
436+ /* cppcheck-suppress uninitvar */
436437 RT_HW_BACKTRACE_FRAME_GET_SELF (& frame );
437438 if (!frame .fp )
438439 return - RT_EINVAL ;
@@ -511,7 +512,7 @@ rt_weak rt_err_t rt_backtrace_to_buffer(rt_thread_t thread,
511512 long buflen )
512513{
513514 long nesting = 0 ;
514- struct rt_hw_backtrace_frame cur_frame ;
515+ struct rt_hw_backtrace_frame cur_frame = { 0 } ;
515516
516517 if (!thread )
517518 return - RT_EINVAL ;
@@ -521,6 +522,7 @@ rt_weak rt_err_t rt_backtrace_to_buffer(rt_thread_t thread,
521522 if (!frame )
522523 {
523524 frame = & cur_frame ;
525+ /* cppcheck-suppress uninitvar */
524526 RT_HW_BACKTRACE_FRAME_GET_SELF (frame );
525527 if (!frame -> fp )
526528 return - RT_EINVAL ;
@@ -745,12 +747,133 @@ rt_uint8_t rt_thread_get_usage(rt_thread_t thread)
745747#endif /* RT_USING_CPU_USAGE_TRACER */
746748
747749#if defined(RT_USING_LIBC ) && defined(RT_USING_FINSH )
750+ #include <limits.h>
748751#include <stdlib.h> /* for string service */
749752
750- static void cmd_backtrace ( int argc , char * * argv )
753+ struct cmd_backtrace_find_ctx
751754{
752755 rt_uintptr_t pid ;
756+ rt_thread_t thread ;
757+ };
758+
759+ static rt_err_t cmd_backtrace_match_thread (struct rt_object * object , void * data )
760+ {
761+ struct cmd_backtrace_find_ctx * ctx = data ;
762+
763+ if ((rt_uintptr_t )object == ctx -> pid )
764+ {
765+ ctx -> thread = (rt_thread_t )object ;
766+
767+ return 1 ;
768+ }
769+
770+ return RT_EOK ;
771+ }
772+
773+ #if UINTPTR_MAX > ULONG_MAX
774+ static void cmd_backtrace_format_pid (rt_uintptr_t pid , char * buf , rt_size_t size )
775+ {
776+ static const char hex [] = "0123456789abcdef" ;
777+ char digits [sizeof (rt_uintptr_t ) * 2 ];
778+ rt_size_t count = 0 ;
779+ rt_size_t index ;
780+
781+ if ((buf == RT_NULL ) || (size < 4 ))
782+ {
783+ if ((buf != RT_NULL ) && (size > 0 ))
784+ {
785+ buf [0 ] = '\0' ;
786+ }
787+ return ;
788+ }
789+
790+ do
791+ {
792+ digits [count ++ ] = hex [pid & 0xf ];
793+ pid >>= 4 ;
794+ }
795+ while ((pid != 0 ) && (count < sizeof (digits )));
796+
797+ buf [0 ] = '0' ;
798+ buf [1 ] = 'x' ;
799+
800+ for (index = 0 ; index < count ; index ++ )
801+ {
802+ buf [2 + index ] = digits [count - index - 1 ];
803+ }
804+
805+ buf [2 + count ] = '\0' ;
806+ }
807+ #endif
808+
809+ static rt_bool_t cmd_backtrace_parse_pid (const char * arg , rt_uintptr_t * pid )
810+ {
753811 char * end_ptr ;
812+ #if UINTPTR_MAX > ULONG_MAX
813+ unsigned long long parsed_value ;
814+ #else
815+ unsigned long parsed_value ;
816+ #endif
817+ rt_uintptr_t value ;
818+
819+ if ((arg == RT_NULL ) || (pid == RT_NULL ))
820+ {
821+ return RT_FALSE ;
822+ }
823+
824+ if ((* arg == '+' ) || (* arg == '-' ))
825+ {
826+ return RT_FALSE ;
827+ }
828+
829+ errno = 0 ;
830+ #if UINTPTR_MAX > ULONG_MAX
831+ parsed_value = strtoull (arg , & end_ptr , 0 );
832+ #else
833+ parsed_value = strtoul (arg , & end_ptr , 0 );
834+ #endif
835+ if ((end_ptr == arg ) || (* end_ptr != '\0' ) ||
836+ (errno == ERANGE ) ||
837+ #if UINTPTR_MAX > ULONG_MAX
838+ (parsed_value > (unsigned long long )(rt_uintptr_t )- 1 ))
839+ #else
840+ (parsed_value > (unsigned long )(rt_uintptr_t )- 1 ))
841+ #endif
842+ {
843+ return RT_FALSE ;
844+ }
845+
846+ value = (rt_uintptr_t )parsed_value ;
847+ if (value == 0 )
848+ {
849+ return RT_FALSE ;
850+ }
851+
852+ * pid = value ;
853+
854+ return RT_TRUE ;
855+ }
856+
857+ static rt_thread_t cmd_backtrace_find_thread (rt_uintptr_t pid )
858+ {
859+ struct cmd_backtrace_find_ctx ctx =
860+ {
861+ .pid = pid ,
862+ .thread = RT_NULL ,
863+ };
864+
865+ rt_object_for_each (RT_Object_Class_Thread , cmd_backtrace_match_thread , & ctx );
866+
867+ return ctx .thread ;
868+ }
869+
870+ static void cmd_backtrace (int argc , char * * argv )
871+ {
872+ rt_uintptr_t pid ;
873+ rt_thread_t target ;
874+ #if UINTPTR_MAX > ULONG_MAX
875+ char pid_buf [sizeof (rt_uintptr_t ) * 2 + 3 ];
876+ #endif
754877
755878 if (argc != 2 )
756879 {
@@ -770,21 +893,34 @@ static void cmd_backtrace(int argc, char** argv)
770893 }
771894 }
772895
773- pid = strtoul (argv [1 ], & end_ptr , 0 );
774- if (end_ptr == argv [1 ])
896+ if (!cmd_backtrace_parse_pid (argv [1 ], & pid ))
775897 {
776898 rt_kprintf ("Invalid input: %s\n" , argv [1 ]);
777899 return ;
778900 }
779901
780- if (pid && rt_object_get_type ((void * )pid ) == RT_Object_Class_Thread )
902+ target = cmd_backtrace_find_thread (pid );
903+ #if UINTPTR_MAX > ULONG_MAX
904+ cmd_backtrace_format_pid (pid , pid_buf , sizeof (pid_buf ));
905+ #endif
906+ if (target != RT_NULL )
781907 {
782- rt_thread_t target = (rt_thread_t )pid ;
783- rt_kprintf ("backtrace %s(0x%lx), from %s\n" , target -> parent .name , pid , argv [1 ]);
908+ #if UINTPTR_MAX > ULONG_MAX
909+ rt_kprintf ("backtrace %s(%s), from %s\n" , target -> parent .name , pid_buf , argv [1 ]);
910+ #else
911+ rt_kprintf ("backtrace %s(0x%lx), from %s\n" ,
912+ target -> parent .name , (unsigned long )pid , argv [1 ]);
913+ #endif
784914 rt_backtrace_thread (target );
785915 }
786916 else
787- rt_kprintf ("Invalid pid: %ld\n" , pid );
917+ {
918+ #if UINTPTR_MAX > ULONG_MAX
919+ rt_kprintf ("Invalid pid: %s\n" , pid_buf );
920+ #else
921+ rt_kprintf ("Invalid pid: %lx\n" , (unsigned long )pid );
922+ #endif
923+ }
788924}
789925MSH_CMD_EXPORT_ALIAS (cmd_backtrace , backtrace , print backtrace of a thread );
790926
0 commit comments