You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by GitBox <gi...@apache.org> on 2021/07/30 04:47:48 UTC

[GitHub] [incubator-nuttx] anchao opened a new pull request #4259: sched/backtrace: add support for printing the arbitrary thread stack in runtime

anchao opened a new pull request #4259:
URL: https://github.com/apache/incubator-nuttx/pull/4259


   ## Summary
   
   add support for printing the arbitrary thread stack in runtime to monitor the thread status
   ( only support cortex-m / cortex-a(thumb) )
   
   libs/libc: move the backtrace implement to sched
   arch/cortex-m: add arch backtrace support 
   sched/backtrace: add sched_backtrace support 
   
   ## Impact
   
   Depends on:
   https://github.com/apache/incubator-nuttx-apps/pull/817
   
   N/A, new feature
   
   ## Testing
   
   Running tasks:
   
   ```
   ap> ps
     PID GROUP PRI POLICY   TYPE    NPX STATE    EVENT     SIGMASK   STACK   USED  FILLED    CPU COMMAND
       0     0   0 FIFO     Kthread N-- Ready              00000000 003052 001044  34.2%   94.4% Idle Task
       1     1 253 RR       Kthread --- Waiting  Semaphore 00000000 003044 000344  11.3%    0.0% hpwork 0x2011dc34
       2     2 253 RR       Kthread --- Waiting  Semaphore 00000000 003044 000344  11.3%    0.0% hpwork 0x2011dc34
       3     3 253 RR       Kthread --- Waiting  Semaphore 00000000 003044 000344  11.3%    0.0% hpwork 0x2011dc34
       4     4 110 RR       Kthread --- Waiting  Semaphore 00000000 008164 000824  10.0%    1.6% lpwork 0x2011dc28
       5     5 110 RR       Kthread --- Waiting  Semaphore 00000000 008164 001592  19.5%    0.0% lpwork 0x2011dc28
       6     6 110 RR       Kthread --- Waiting  Semaphore 00000000 008164 001544  18.9%    0.5% lpwork 0x2011dc28
       8     8 101 RR       Kthread --- Waiting  Semaphore 00000000 004060 001896  46.6%    0.0% bes_main  0x34008650
       9     9 252 RR       Kthread --- Waiting  MQ empty  00000000 006108 000488   7.9%    0.0% app_thread  0x34007924
      10    10 253 RR       Kthread --- Waiting  Semaphore 00000000 008124 000504   6.2%    0.0% audio_flinger  0x20042968
      11    11 100 RR       Kthread --- Waiting  Signal    00000000 003028 000472  15.5%    0.0% apps_recover  0x34007944
      12    12 252 RR       Kthread --- Waiting  MQ empty  00000000 010180 000504   4.9%    0.0% net_wq  0x20044d60
      13    13 252 RR       Kthread --- Waiting  MQ empty  00000000 008132 000480   5.9%    0.0% net_tasklet  0x20044d28
      14    14 252 RR       Kthread --- Waiting  Semaphore 00000000 004036 000920  22.7%    0.0% cw1200_bh  0x20044e14
      15    15 224 RR       Kthread --- Waiting  Semaphore 00000000 004060 000636  15.6%    0.0% rptun audio 0x20147250
      16    16 100 RR       Task    --- Waiting  Semaphore 00000000 004060 000368   9.0%    0.0% rc_raw_event_thx 0x20148f70
      17    17 100 RR       Task    --- Running            00000000 004084 001824  44.6%    0.5% init
      18    18 100 RR       Task    --- Waiting  Semaphore 00000000 004084 002384  58.3%    0.0% kvdbd
      20    20 252 RR       Task    --- Waiting  Semaphore 00000000 004060 000536  13.2%    0.0% rpmsg-uorb-audio 0x20157650
      21    21 232 RR       Task    --- Waiting  Semaphore 00000000 006132 001808  29.4%    0.0% usrsock
      23    23 227 FIFO     Kthread --- Waiting  Semaphore 00000000 001984 000712  35.8%    0.0% BT TX  0x201575f0
      24    24 228 FIFO     Kthread --- Waiting  Semaphore 00000000 004032 000880  21.8%    0.5% BT RX  0x201575f0
      25    25 230 FIFO     Kthread --- Waiting  Semaphore 00000000 001984 000576  29.0%    0.0% BT ECC  0x201575f0
      26    26 228 FIFO     Kthread --- Waiting  Semaphore 00000000 004032 000944  23.4%    2.7% BT Driver  0x201575f0
      27    27 101 RR       Kthread --- Waiting  MQ empty  00000000 004060 000608  14.9%    0.0% wifi_event  0x34008524
      28    28 252 RR       Kthread --- Waiting  MQ empty  00000000 004052 000568  14.0%    0.0% bes_netdev_wq
      29    29 100 RR       Kthread --- Waiting  Signal    00000000 004052 000520  12.8%    0.0% trans_stat_task  0x34008504
      30    30 100 RR       Kthread --- Ready              00000000 003036 000552  18.1%    0.0% temp_main  0x34008630
   
   ```
   
   show task 1 hpwork:
   
   ```
   ap> dumpstack 1
   [06:14:18] [32] [BackTrace| 1|0]:   0xc0e635c   0x2111b6   0x2111d6  0xc0d7b06   0x2128a8
   ```
   
   check the backtrace:
   ```
   arm-none-eabi-addr2line -e nuttx 0xc0e635c   0x2111b6   0x2111d6  0xc0d7b06   0x2128a8
   /home/archer/code/m3/nuttx/arch/arm/src/armv8-m/arm_switchcontext.S:79
   /home/archer/code/m3/nuttx/sched/semaphore/sem_wait.c:153 (discriminator 2)
   /home/archer/code/m3/nuttx/sched/semaphore/sem_wait.c:222 (discriminator 1)
   /home/archer/code/m3/nuttx/sched/wqueue/kwork_thread.c:132
   /home/archer/code/m3/nuttx/sched/task/task_start.c:139
   ```
   
   dump stack in range 0 - 30:
   
   ```
   ap> dumpstack 0 30
   [06:14:27] [33] [BackTrace| 0|0]:    0x240420   0x240184 0x2400460b
   [06:14:27] [33] [BackTrace| 1|0]:   0xc0e635c   0x2111b6   0x2111d6  0xc0d7b06   0x2128a8
   [06:14:27] [33] [BackTrace| 2|0]:   0xc0e635c   0x2111b6   0x2111d6  0xc0d7b06   0x2128a8
   [06:14:27] [33] [BackTrace| 3|0]:   0xc0e635c   0x2111b6   0x2111d6  0xc0d7b06   0x2128a8
   [06:14:27] [33] [BackTrace| 4|0]:   0xc0e635c   0x2111b6   0x2111d6  0xc0d7b06   0x2128a8
   [06:14:27] [33] [BackTrace| 5|0]:   0xc0e635c   0x2111b6   0x2111d6  0xc0d7b06   0x2128a8
   [06:14:27] [33] [BackTrace| 6|0]:   0xc0e635c   0x2111b6   0x2111d6  0xc0d7b06   0x2128a8
   [06:14:27] [33] [BackTrace| 8|0]:   0xc0e635c   0x2111b6   0x2111d6   0x2103a4   0x210170   0x222556  0xc1ddad0   0x2128a8
   [06:14:27] [33] [BackTrace| 9|0]:   0xc0e635c   0x20f8b6   0x20f68e   0x222b1e  0xc1b066a  0xc1b0696   0x2128a8
   [06:14:27] [33] [BackTrace|10|0]:   0xc0e635c   0x2111b6   0x2111d6   0x2103a4   0x210170   0x222556   0x20df16   0x2128a8
   [06:14:27] [33] [BackTrace|11|0]:   0xc0e635c   0x211b6a   0x2121a8   0x212268  0xc0e5080  0xc1f6724   0x2128a8
   [06:14:27] [33] [BackTrace|12|0]:   0xc0e635c   0x20f8b6   0x20f68e   0x222b1e   0x22d968   0x2128a8
   [06:14:27] [33] [BackTrace|13|0]:   0xc0e635c   0x20f8b6   0x20f68e   0x2229ac   0x22e702   0x2128a8
   [06:14:27] [33] [BackTrace|14|0]:   0xc0e635c   0x2111b6   0x2111e2   0x222732   0x23e90e   0x2128a8
   [06:14:27] [33] [BackTrace|15|0]:   0xc0e635c   0x2111b6   0x2113a0   0x2113da  0xc0daa9c   0x2128a8
   [06:14:27] [33] [BackTrace|16|0]:   0xc0e635c   0x2111b6  0xc0e7b62  0xc0e07e4   0x2128bc
   [06:14:27] [33] [BackTrace|17|0]:   0xc0e635c   0x211bac   0x210d38   0x210d8e  0xc0fd872  0xc0fa42a  0xc0fd4e4  0xc0fe43c
   [06:14:27] [33] [BackTrace|17|1]:   0xc0fe912  0xc0e07e4   0x2128bc
   [06:14:27] [33] [BackTrace|18|0]:   0xc0e635c   0x2111b6  0xc196746  0xc1967b6  0xc134324  0xc1345dc  0xc0e07e4   0x2128bc
   [06:14:27] [33] [BackTrace|20|0]:   0xc0e635c   0x2111b6  0xc196746  0xc1967b6   0x2122fa  0xc108db4  0xc0e07e4   0x2128bc
   [06:14:27] [33] [BackTrace|21|0]:   0xc0e635c   0x2111b6  0xc196746  0xc1967b6  0xc103e1c 0xdeadbeec
   [06:14:27] [33] [BackTrace|23|0]:   0xc0e635c   0x2111b6   0x2111e2  0xc16f02e  0xc16ecee  0xc154a90  0xc16f36a   0x2128a8
   [06:14:27] [33] [BackTrace|24|0]:   0xc0e635c   0x2111b6   0x2111e2  0xc16f02e  0xc16ecee  0xc16f2c2  0xc16f5f0  0xc15494c
   [06:14:27] [33] [BackTrace|24|1]:   0xc16f36a   0x2128a8
   [06:14:27] [33] [BackTrace|25|0]:   0xc0e635c   0x2111b6   0x2111e2  0xc16f02e  0xc15381c  0xc16f36a   0x2128a8
   [06:14:27] [33] [BackTrace|26|0]:   0xc0e635c   0x2111b6   0x2111d6  0xc0e8d9e  0xc0dd790  0xc0dd82c  0xc16fb80  0xc16fbbe
   [06:14:27] [33] [BackTrace|26|1]:   0xc16f36a   0x2128a8
   [06:14:27] [33] [BackTrace|27|0]:   0xc0e635c   0x20f8b6   0x20f68e   0x222b1e  0xc1d4b3c   0x2128a8
   [06:14:27] [33] [BackTrace|28|0]:   0xc0e635c   0x20f8b6   0x20f68e   0x223b04   0x2128a8
   [06:14:27] [33] [BackTrace|29|0]:   0xc0e635c   0x211b6a   0x2121a8   0x212268  0xc0e5080  0xc1d419a   0x2128a8
   [06:14:27] [33] [BackTrace|30|0]:   0xc0e635c   0x211b6a   0x2121a8   0x212268  0xc0e5080  0xc1dd748   0x2128a8
   ```
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] anchao commented on pull request #4259: sched/backtrace: add support for printing the arbitrary thread backtrace in runtime

Posted by GitBox <gi...@apache.org>.
anchao commented on pull request #4259:
URL: https://github.com/apache/incubator-nuttx/pull/4259#issuecomment-905479004


   let us close this PR since I have split the commit to other PR, please refer: 
   https://github.com/apache/incubator-nuttx/pull/4409 
   https://github.com/apache/incubator-nuttx/pull/4405


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] anchao closed pull request #4259: sched/backtrace: add support for printing the arbitrary thread backtrace in runtime

Posted by GitBox <gi...@apache.org>.
anchao closed pull request #4259:
URL: https://github.com/apache/incubator-nuttx/pull/4259


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #4259: sched/backtrace: add support for printing the arbitrary thread backtrace in runtime

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4259:
URL: https://github.com/apache/incubator-nuttx/pull/4259#discussion_r680886726



##########
File path: arch/arm/src/arm/arm_backtrace.c
##########
@@ -0,0 +1,315 @@
+/****************************************************************************
+ * arch/arm/src/arm/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ *
+ * Description:
+ *  getlroffset()  returns the currect link address offset.
+ *
+ * Input Parameters:
+ *   lr    - Link register address
+ *
+ * Returned Value:
+ *   Link address offset, 0 is returned if the lr is invalid.
+ *
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal
+ *
+ * Description:
+ *  backtrace_internal()  returns the currect link address from input program

Review comment:
       currect => current

##########
File path: arch/arm/src/armv6-m/arm_backtrace.c
##########
@@ -0,0 +1,313 @@
+/****************************************************************************
+ * arch/arm/src/armv6-m/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ *
+ * Description:
+ *  getlroffset()  returns the currect link address offset.

Review comment:
       currect => current

##########
File path: arch/arm/src/armv7-r/arm_backtrace.c
##########
@@ -0,0 +1,316 @@
+/****************************************************************************
+ * arch/arm/src/armv7-r/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ *
+ * Description:
+ *  getlroffset()  returns the currect link address offset.
+ *
+ * Input Parameters:
+ *   lr    - Link register address
+ *
+ * Returned Value:
+ *   Link address offset, 0 is returned if the lr is invalid.
+ *
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal
+ *
+ * Description:
+ *  backtrace_internal()  returns the currect link address from input program

Review comment:
       ditto

##########
File path: arch/arm/src/armv8-m/arm_backtrace.c
##########
@@ -0,0 +1,313 @@
+/****************************************************************************
+ * arch/arm/src/armv8-m/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ *
+ * Description:
+ *  getlroffset()  returns the currect link address offset.
+ *
+ * Input Parameters:
+ *   lr    - Link register address
+ *
+ * Returned Value:
+ *   Link address offset, 0 is returned if the lr is invalid.
+ *
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal
+ *
+ * Description:
+ *  backtrace_internal()  returns the currect link address from input program

Review comment:
       ditto

##########
File path: arch/arm/src/armv7-a/arm_backtrace.c
##########
@@ -0,0 +1,315 @@
+/****************************************************************************
+ * arch/arm/src/armv7-a/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ *
+ * Description:
+ *  getlroffset()  returns the currect link address offset.

Review comment:
       ditto

##########
File path: arch/arm/src/armv7-r/arm_backtrace.c
##########
@@ -0,0 +1,316 @@
+/****************************************************************************
+ * arch/arm/src/armv7-r/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ *
+ * Description:
+ *  getlroffset()  returns the currect link address offset.

Review comment:
       ditto

##########
File path: arch/arm/src/armv7-a/arm_backtrace.c
##########
@@ -0,0 +1,315 @@
+/****************************************************************************
+ * arch/arm/src/armv7-a/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ *
+ * Description:
+ *  getlroffset()  returns the currect link address offset.
+ *
+ * Input Parameters:
+ *   lr    - Link register address
+ *
+ * Returned Value:
+ *   Link address offset, 0 is returned if the lr is invalid.
+ *
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal
+ *
+ * Description:
+ *  backtrace_internal()  returns the currect link address from input program

Review comment:
       ditto

##########
File path: arch/arm/src/arm/arm_backtrace.c
##########
@@ -0,0 +1,315 @@
+/****************************************************************************
+ * arch/arm/src/arm/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ *
+ * Description:
+ *  getlroffset()  returns the currect link address offset.

Review comment:
       ditto

##########
File path: arch/arm/src/armv7-m/arm_backtrace.c
##########
@@ -0,0 +1,313 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ *
+ * Description:
+ *  getlroffset()  returns the currect link address offset.
+ *
+ * Input Parameters:
+ *   lr    - Link register address
+ *
+ * Returned Value:
+ *   Link address offset, 0 is returned if the lr is invalid.
+ *
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal
+ *
+ * Description:
+ *  backtrace_internal()  returns the currect link address from input program

Review comment:
       ditto

##########
File path: arch/arm/src/armv8-m/arm_backtrace.c
##########
@@ -0,0 +1,313 @@
+/****************************************************************************
+ * arch/arm/src/armv8-m/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ *
+ * Description:
+ *  getlroffset()  returns the currect link address offset.

Review comment:
       ditto

##########
File path: arch/arm/src/armv7-m/arm_backtrace.c
##########
@@ -0,0 +1,313 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ *
+ * Description:
+ *  getlroffset()  returns the currect link address offset.

Review comment:
       ditto

##########
File path: arch/arm/src/armv6-m/arm_backtrace.c
##########
@@ -0,0 +1,313 @@
+/****************************************************************************
+ * arch/arm/src/armv6-m/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ *
+ * Description:
+ *  getlroffset()  returns the currect link address offset.
+ *
+ * Input Parameters:
+ *   lr    - Link register address
+ *
+ * Returned Value:
+ *   Link address offset, 0 is returned if the lr is invalid.
+ *
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal
+ *
+ * Description:
+ *  backtrace_internal()  returns the currect link address from input program

Review comment:
       ditto




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] anchao commented on pull request #4259: sched/backtrace: add support for printing the arbitrary thread backtrace in runtime

Posted by GitBox <gi...@apache.org>.
anchao commented on pull request #4259:
URL: https://github.com/apache/incubator-nuttx/pull/4259#issuecomment-890691789


   @acassis please review again, thank you!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on pull request #4259: sched/backtrace: add support for printing the arbitrary thread backtrace in runtime

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on pull request #4259:
URL: https://github.com/apache/incubator-nuttx/pull/4259#issuecomment-894602042


   @acassis could review again?


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] acassis commented on a change in pull request #4259: sched/backtrace: add support for printing the arbitrary thread backtrace in runtime

Posted by GitBox <gi...@apache.org>.
acassis commented on a change in pull request #4259:
URL: https://github.com/apache/incubator-nuttx/pull/4259#discussion_r680093811



##########
File path: arch/arm/src/arm/arm_backtrace.c
##########
@@ -0,0 +1,268 @@
+/****************************************************************************
+ * arch/arm/src/arm/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal
+ ****************************************************************************/

Review comment:
       Please include a complete Description of the function, including params and return

##########
File path: arch/arm/src/arm/arm_backtrace.c
##########
@@ -0,0 +1,268 @@
+/****************************************************************************
+ * arch/arm/src/arm/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal
+ ****************************************************************************/
+
+static FAR void *backtrace_internal(FAR void **psp, FAR void **ppc,
+                                    FAR void *addr)
+{
+  FAR uint8_t *sp = *psp;
+  FAR uint8_t *pc = *ppc;
+  FAR uint8_t *base;
+  FAR uint8_t *lr;
+  uint32_t ins32;
+  uint16_t ins16;
+  int offset;
+  int frame;
+  int i;
+
+  if (*psp >= addr)
+    {
+      return NULL;
+    }
+
+  offset = 1;
+
+  for (i = 2; i < INSTR_LIMIT; i += 2)
+    {
+      ins16 = *(FAR uint16_t *)(pc - i);
+      if (INSTR_IS(ins16, T_PUSH))
+        {
+          frame = __builtin_popcount(ins16 & 0xff) + 1;
+          ins16 = *(FAR uint16_t *)(pc - i - 2);
+          if (INSTR_IS(ins16, T_PUSH_LO))
+            {
+              offset = __builtin_popcount(ins16 & 0xff);
+              frame += offset;
+            }
+
+          break;
+        }
+
+      ins32  = ins16 << 16;
+      ins32 |= *(FAR uint16_t *)(pc - i + 2);
+      if (INSTR_IS(ins32, T_STMDB))
+        {
+          frame = __builtin_popcount(ins32 & 0xfff) + 1;
+          break;
+        }
+    }
+
+  if (i >= INSTR_LIMIT)
+    {
+      return NULL;
+    }
+
+  base = pc - i;
+
+  i = 0;
+
+  while (i < INSTR_LIMIT && base + i < pc)
+    {
+      ins16 = *(FAR uint16_t *)(base + i);
+      if (INSTR_IS(ins16, T_SUB_SP_16))
+        {
+          frame += (ins16 & 0x7f);
+          break;
+        }
+
+      ins32  = ins16 << 16;
+      ins32 |= *(FAR uint16_t *)(base + i + 2);
+      if (INSTR_IS(ins32, T_SUB_SP_32))
+        {
+          uint32_t shift;
+          uint32_t sub;
+
+          sub    = (ins32 & 0x7f) + 0x80;
+          shift  = (ins32 >> 7) & 0x1;
+          shift += ((ins32 >> 12) & 0x7) << 1;
+          shift += ((ins32 >> 26) & 0x1) << 4;
+
+          frame += sub << (30 - shift);
+          break;
+        }
+      else if (INSTR_IS(ins32, T_VPUSH_16))
+        {
+          frame += (ins32 & 0xff);
+        }
+      else if (INSTR_IS(ins32, T_VPUSH_8))
+        {
+          frame += (ins32 & 0xff) / 2;
+        }
+
+      i += ((ins16 & 0xf800) >= 0xe800) ? 4 : 2;
+    }
+
+  lr = (FAR uint8_t *)*((FAR uint32_t *)sp + frame - offset);
+  if (lr == NULL)
+    {
+      return NULL;
+    }
+
+  offset = getlroffset(lr);
+  if (offset == 0)
+    {
+      return NULL;
+    }
+
+  *psp   = (FAR uint32_t *)sp + frame;
+  *ppc   = lr - offset;
+
+  return *ppc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_backtrace
+ ****************************************************************************/
+
+int up_backtrace(FAR struct tcb_s *tcb, FAR void **buffer, int size)
+{
+  FAR struct tcb_s *rtcb;
+  irqstate_t flags;
+  FAR void *sp;
+  FAR void *lr;
+  int i;
+
+#ifdef CONFIG_ARM_THUMB
+  if (!tcb || size <= 0 || !buffer)
+#endif
+    {
+      return 0;
+    }
+
+  flags = enter_critical_section();
+
+  i = 0;
+
+  rtcb = this_task();
+
+  if (rtcb == tcb)
+    {
+      lr = (FAR uint8_t *)up_backtrace + 0x10;
+      sp = (FAR void *)arm_getsp();
+
+      buffer[i++] = up_backtrace;
+    }
+  else
+    {
+      lr = (FAR void *)tcb->xcp.regs[REG_LR];
+      sp = (FAR void *)tcb->xcp.regs[REG_SP];
+
+      buffer[i++] = (FAR void *)tcb->xcp.regs[REG_PC];
+    }
+
+  if (size == 1)
+    {
+      leave_critical_section(flags);
+      return size;
+    }
+
+  lr = (FAR uint8_t *)lr - getlroffset(lr);
+
+  if (rtcb != tcb)
+    {
+      buffer[i++] = lr;
+    }
+
+  for (; i < size; i++)
+    {
+      buffer[i] = backtrace_internal(&sp, &lr,
+                  tcb->stack_alloc_ptr + tcb->adj_stack_size);

Review comment:
       Please align this line to start after the "(" from previous line

##########
File path: arch/arm/src/armv7-r/arm_backtrace.c
##########
@@ -0,0 +1,268 @@
+/****************************************************************************
+ * arch/arm/src/armv7-r/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset

Review comment:
       ditto

##########
File path: arch/arm/src/armv7-r/arm_backtrace.c
##########
@@ -0,0 +1,268 @@
+/****************************************************************************
+ * arch/arm/src/armv7-r/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal

Review comment:
       ditto

##########
File path: arch/arm/src/armv7-a/arm_backtrace.c
##########
@@ -0,0 +1,268 @@
+/****************************************************************************
+ * arch/arm/src/armv7-a/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ ****************************************************************************/

Review comment:
       ditto

##########
File path: arch/arm/src/armv6-m/arm_backtrace.c
##########
@@ -0,0 +1,266 @@
+/****************************************************************************
+ * arch/arm/src/armv6-m/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal
+ ****************************************************************************/
+
+static FAR void *backtrace_internal(FAR void **psp, FAR void **ppc,
+                                    FAR void *addr)
+{
+  FAR uint8_t *sp = *psp;
+  FAR uint8_t *pc = *ppc;
+  FAR uint8_t *base;
+  FAR uint8_t *lr;
+  uint32_t ins32;
+  uint16_t ins16;
+  int offset;
+  int frame;
+  int i;
+
+  if (*psp >= addr)
+    {
+      return NULL;
+    }
+
+  offset = 1;
+
+  for (i = 2; i < INSTR_LIMIT; i += 2)
+    {
+      ins16 = *(FAR uint16_t *)(pc - i);
+      if (INSTR_IS(ins16, T_PUSH))
+        {
+          frame = __builtin_popcount(ins16 & 0xff) + 1;
+          ins16 = *(FAR uint16_t *)(pc - i - 2);
+          if (INSTR_IS(ins16, T_PUSH_LO))
+            {
+              offset = __builtin_popcount(ins16 & 0xff);
+              frame += offset;
+            }
+
+          break;
+        }
+
+      ins32  = ins16 << 16;
+      ins32 |= *(FAR uint16_t *)(pc - i + 2);
+      if (INSTR_IS(ins32, T_STMDB))
+        {
+          frame = __builtin_popcount(ins32 & 0xfff) + 1;
+          break;
+        }
+    }
+
+  if (i >= INSTR_LIMIT)
+    {
+      return NULL;
+    }
+
+  base = pc - i;
+
+  i = 0;
+
+  while (i < INSTR_LIMIT && base + i < pc)
+    {
+      ins16 = *(FAR uint16_t *)(base + i);
+      if (INSTR_IS(ins16, T_SUB_SP_16))
+        {
+          frame += (ins16 & 0x7f);
+          break;
+        }
+
+      ins32  = ins16 << 16;
+      ins32 |= *(FAR uint16_t *)(base + i + 2);
+      if (INSTR_IS(ins32, T_SUB_SP_32))
+        {
+          uint32_t shift;
+          uint32_t sub;
+
+          sub    = (ins32 & 0x7f) + 0x80;
+          shift  = (ins32 >> 7) & 0x1;
+          shift += ((ins32 >> 12) & 0x7) << 1;
+          shift += ((ins32 >> 26) & 0x1) << 4;
+
+          frame += sub << (30 - shift);
+          break;
+        }
+      else if (INSTR_IS(ins32, T_VPUSH_16))
+        {
+          frame += (ins32 & 0xff);
+        }
+      else if (INSTR_IS(ins32, T_VPUSH_8))
+        {
+          frame += (ins32 & 0xff) / 2;
+        }
+
+      i += ((ins16 & 0xf800) >= 0xe800) ? 4 : 2;
+    }
+
+  lr = (FAR uint8_t *)*((FAR uint32_t *)sp + frame - offset);
+  if (lr == NULL)
+    {
+      return NULL;
+    }
+
+  offset = getlroffset(lr);
+  if (offset == 0)
+    {
+      return NULL;
+    }
+
+  *psp   = (FAR uint32_t *)sp + frame;
+  *ppc   = lr - offset;
+
+  return *ppc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_backtrace
+ ****************************************************************************/

Review comment:
       ditto

##########
File path: arch/arm/src/armv6-m/arm_backtrace.c
##########
@@ -0,0 +1,266 @@
+/****************************************************************************
+ * arch/arm/src/armv6-m/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ ****************************************************************************/

Review comment:
       ditto

##########
File path: arch/arm/src/armv7-m/arm_backtrace.c
##########
@@ -0,0 +1,266 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset

Review comment:
       ditto

##########
File path: arch/arm/src/armv6-m/arm_backtrace.c
##########
@@ -0,0 +1,266 @@
+/****************************************************************************
+ * arch/arm/src/armv6-m/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal
+ ****************************************************************************/

Review comment:
       ditto

##########
File path: arch/arm/src/armv7-a/arm_backtrace.c
##########
@@ -0,0 +1,268 @@
+/****************************************************************************
+ * arch/arm/src/armv7-a/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal

Review comment:
       ditto

##########
File path: arch/arm/src/arm/arm_backtrace.c
##########
@@ -0,0 +1,268 @@
+/****************************************************************************
+ * arch/arm/src/arm/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal
+ ****************************************************************************/
+
+static FAR void *backtrace_internal(FAR void **psp, FAR void **ppc,
+                                    FAR void *addr)
+{
+  FAR uint8_t *sp = *psp;
+  FAR uint8_t *pc = *ppc;
+  FAR uint8_t *base;
+  FAR uint8_t *lr;
+  uint32_t ins32;
+  uint16_t ins16;
+  int offset;
+  int frame;
+  int i;
+
+  if (*psp >= addr)
+    {
+      return NULL;
+    }
+
+  offset = 1;
+
+  for (i = 2; i < INSTR_LIMIT; i += 2)
+    {
+      ins16 = *(FAR uint16_t *)(pc - i);
+      if (INSTR_IS(ins16, T_PUSH))
+        {
+          frame = __builtin_popcount(ins16 & 0xff) + 1;
+          ins16 = *(FAR uint16_t *)(pc - i - 2);
+          if (INSTR_IS(ins16, T_PUSH_LO))
+            {
+              offset = __builtin_popcount(ins16 & 0xff);
+              frame += offset;
+            }
+
+          break;
+        }
+
+      ins32  = ins16 << 16;
+      ins32 |= *(FAR uint16_t *)(pc - i + 2);
+      if (INSTR_IS(ins32, T_STMDB))
+        {
+          frame = __builtin_popcount(ins32 & 0xfff) + 1;
+          break;
+        }
+    }
+
+  if (i >= INSTR_LIMIT)
+    {
+      return NULL;
+    }
+
+  base = pc - i;
+
+  i = 0;
+
+  while (i < INSTR_LIMIT && base + i < pc)
+    {
+      ins16 = *(FAR uint16_t *)(base + i);
+      if (INSTR_IS(ins16, T_SUB_SP_16))
+        {
+          frame += (ins16 & 0x7f);
+          break;
+        }
+
+      ins32  = ins16 << 16;
+      ins32 |= *(FAR uint16_t *)(base + i + 2);
+      if (INSTR_IS(ins32, T_SUB_SP_32))
+        {
+          uint32_t shift;
+          uint32_t sub;
+
+          sub    = (ins32 & 0x7f) + 0x80;
+          shift  = (ins32 >> 7) & 0x1;
+          shift += ((ins32 >> 12) & 0x7) << 1;
+          shift += ((ins32 >> 26) & 0x1) << 4;
+
+          frame += sub << (30 - shift);
+          break;
+        }
+      else if (INSTR_IS(ins32, T_VPUSH_16))
+        {
+          frame += (ins32 & 0xff);
+        }
+      else if (INSTR_IS(ins32, T_VPUSH_8))
+        {
+          frame += (ins32 & 0xff) / 2;
+        }
+
+      i += ((ins16 & 0xf800) >= 0xe800) ? 4 : 2;
+    }
+
+  lr = (FAR uint8_t *)*((FAR uint32_t *)sp + frame - offset);
+  if (lr == NULL)
+    {
+      return NULL;
+    }
+
+  offset = getlroffset(lr);
+  if (offset == 0)
+    {
+      return NULL;
+    }
+
+  *psp   = (FAR uint32_t *)sp + frame;
+  *ppc   = lr - offset;
+
+  return *ppc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_backtrace
+ ****************************************************************************/

Review comment:
       Please include a complete Description of the function, including params and return

##########
File path: arch/arm/src/armv7-m/arm_backtrace.c
##########
@@ -0,0 +1,266 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal
+ ****************************************************************************/
+
+static FAR void *backtrace_internal(FAR void **psp, FAR void **ppc,
+                                    FAR void *addr)
+{
+  FAR uint8_t *sp = *psp;
+  FAR uint8_t *pc = *ppc;
+  FAR uint8_t *base;
+  FAR uint8_t *lr;
+  uint32_t ins32;
+  uint16_t ins16;
+  int offset;
+  int frame;
+  int i;
+
+  if (*psp >= addr)
+    {
+      return NULL;
+    }
+
+  offset = 1;
+
+  for (i = 2; i < INSTR_LIMIT; i += 2)
+    {
+      ins16 = *(FAR uint16_t *)(pc - i);
+      if (INSTR_IS(ins16, T_PUSH))
+        {
+          frame = __builtin_popcount(ins16 & 0xff) + 1;
+          ins16 = *(FAR uint16_t *)(pc - i - 2);
+          if (INSTR_IS(ins16, T_PUSH_LO))
+            {
+              offset = __builtin_popcount(ins16 & 0xff);
+              frame += offset;
+            }
+
+          break;
+        }
+
+      ins32  = ins16 << 16;
+      ins32 |= *(FAR uint16_t *)(pc - i + 2);
+      if (INSTR_IS(ins32, T_STMDB))
+        {
+          frame = __builtin_popcount(ins32 & 0xfff) + 1;
+          break;
+        }
+    }
+
+  if (i >= INSTR_LIMIT)
+    {
+      return NULL;
+    }
+
+  base = pc - i;
+
+  i = 0;
+
+  while (i < INSTR_LIMIT && base + i < pc)
+    {
+      ins16 = *(FAR uint16_t *)(base + i);
+      if (INSTR_IS(ins16, T_SUB_SP_16))
+        {
+          frame += (ins16 & 0x7f);
+          break;
+        }
+
+      ins32  = ins16 << 16;
+      ins32 |= *(FAR uint16_t *)(base + i + 2);
+      if (INSTR_IS(ins32, T_SUB_SP_32))
+        {
+          uint32_t shift;
+          uint32_t sub;
+
+          sub    = (ins32 & 0x7f) + 0x80;
+          shift  = (ins32 >> 7) & 0x1;
+          shift += ((ins32 >> 12) & 0x7) << 1;
+          shift += ((ins32 >> 26) & 0x1) << 4;
+
+          frame += sub << (30 - shift);
+          break;
+        }
+      else if (INSTR_IS(ins32, T_VPUSH_16))
+        {
+          frame += (ins32 & 0xff);
+        }
+      else if (INSTR_IS(ins32, T_VPUSH_8))
+        {
+          frame += (ins32 & 0xff) / 2;
+        }
+
+      i += ((ins16 & 0xf800) >= 0xe800) ? 4 : 2;
+    }
+
+  lr = (FAR uint8_t *)*((FAR uint32_t *)sp + frame - offset);
+  if (lr == NULL)
+    {
+      return NULL;
+    }
+
+  offset = getlroffset(lr);
+  if (offset == 0)
+    {
+      return NULL;
+    }
+
+  *psp   = (FAR uint32_t *)sp + frame;
+  *ppc   = lr - offset;
+
+  return *ppc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_backtrace

Review comment:
       ditto

##########
File path: arch/arm/src/armv7-a/arm_backtrace.c
##########
@@ -0,0 +1,268 @@
+/****************************************************************************
+ * arch/arm/src/armv7-a/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal
+ ****************************************************************************/
+
+static FAR void *backtrace_internal(FAR void **psp, FAR void **ppc,
+                                    FAR void *addr)
+{
+  FAR uint8_t *sp = *psp;
+  FAR uint8_t *pc = *ppc;
+  FAR uint8_t *base;
+  FAR uint8_t *lr;
+  uint32_t ins32;
+  uint16_t ins16;
+  int offset;
+  int frame;
+  int i;
+
+  if (*psp >= addr)
+    {
+      return NULL;
+    }
+
+  offset = 1;
+
+  for (i = 2; i < INSTR_LIMIT; i += 2)
+    {
+      ins16 = *(FAR uint16_t *)(pc - i);
+      if (INSTR_IS(ins16, T_PUSH))
+        {
+          frame = __builtin_popcount(ins16 & 0xff) + 1;
+          ins16 = *(FAR uint16_t *)(pc - i - 2);
+          if (INSTR_IS(ins16, T_PUSH_LO))
+            {
+              offset = __builtin_popcount(ins16 & 0xff);
+              frame += offset;
+            }
+
+          break;
+        }
+
+      ins32  = ins16 << 16;
+      ins32 |= *(FAR uint16_t *)(pc - i + 2);
+      if (INSTR_IS(ins32, T_STMDB))
+        {
+          frame = __builtin_popcount(ins32 & 0xfff) + 1;
+          break;
+        }
+    }
+
+  if (i >= INSTR_LIMIT)
+    {
+      return NULL;
+    }
+
+  base = pc - i;
+
+  i = 0;
+
+  while (i < INSTR_LIMIT && base + i < pc)
+    {
+      ins16 = *(FAR uint16_t *)(base + i);
+      if (INSTR_IS(ins16, T_SUB_SP_16))
+        {
+          frame += (ins16 & 0x7f);
+          break;
+        }
+
+      ins32  = ins16 << 16;
+      ins32 |= *(FAR uint16_t *)(base + i + 2);
+      if (INSTR_IS(ins32, T_SUB_SP_32))
+        {
+          uint32_t shift;
+          uint32_t sub;
+
+          sub    = (ins32 & 0x7f) + 0x80;
+          shift  = (ins32 >> 7) & 0x1;
+          shift += ((ins32 >> 12) & 0x7) << 1;
+          shift += ((ins32 >> 26) & 0x1) << 4;
+
+          frame += sub << (30 - shift);
+          break;
+        }
+      else if (INSTR_IS(ins32, T_VPUSH_16))
+        {
+          frame += (ins32 & 0xff);
+        }
+      else if (INSTR_IS(ins32, T_VPUSH_8))
+        {
+          frame += (ins32 & 0xff) / 2;
+        }
+
+      i += ((ins16 & 0xf800) >= 0xe800) ? 4 : 2;
+    }
+
+  lr = (FAR uint8_t *)*((FAR uint32_t *)sp + frame - offset);
+  if (lr == NULL)
+    {
+      return NULL;
+    }
+
+  offset = getlroffset(lr);
+  if (offset == 0)
+    {
+      return NULL;
+    }
+
+  *psp   = (FAR uint32_t *)sp + frame;
+  *ppc   = lr - offset;
+
+  return *ppc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_backtrace

Review comment:
       ditto

##########
File path: arch/arm/src/armv7-m/arm_backtrace.c
##########
@@ -0,0 +1,266 @@
+/****************************************************************************
+ * arch/arm/src/armv7-m/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal

Review comment:
       ditto

##########
File path: arch/arm/src/armv8-m/arm_backtrace.c
##########
@@ -0,0 +1,266 @@
+/****************************************************************************
+ * arch/arm/src/armv8-m/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions

Review comment:
       ditto

##########
File path: include/nuttx/arch.h
##########
@@ -493,6 +493,18 @@ void up_exit() noreturn_function;
 
 void up_assert(FAR const char *filename, int linenum);
 
+/****************************************************************************
+ * Name: up_backtrace
+ *
+ * Description:
+ *  Dump thread backtrace from specified tcb
+ *

Review comment:
       please include params info and return

##########
File path: arch/arm/src/armv8-m/arm_backtrace.c
##########
@@ -0,0 +1,266 @@
+/****************************************************************************
+ * arch/arm/src/armv8-m/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset

Review comment:
       ditto

##########
File path: arch/arm/src/armv8-m/arm_backtrace.c
##########
@@ -0,0 +1,266 @@
+/****************************************************************************
+ * arch/arm/src/armv8-m/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal
+ ****************************************************************************/
+
+static FAR void *backtrace_internal(FAR void **psp, FAR void **ppc,
+                                    FAR void *addr)
+{
+  FAR uint8_t *sp = *psp;
+  FAR uint8_t *pc = *ppc;
+  FAR uint8_t *base;
+  FAR uint8_t *lr;
+  uint32_t ins32;
+  uint16_t ins16;
+  int offset;
+  int frame;
+  int i;
+
+  if (*psp >= addr)
+    {
+      return NULL;
+    }
+
+  offset = 1;
+
+  for (i = 2; i < INSTR_LIMIT; i += 2)
+    {
+      ins16 = *(FAR uint16_t *)(pc - i);
+      if (INSTR_IS(ins16, T_PUSH))
+        {
+          frame = __builtin_popcount(ins16 & 0xff) + 1;
+          ins16 = *(FAR uint16_t *)(pc - i - 2);
+          if (INSTR_IS(ins16, T_PUSH_LO))
+            {
+              offset = __builtin_popcount(ins16 & 0xff);
+              frame += offset;
+            }
+
+          break;
+        }
+
+      ins32  = ins16 << 16;
+      ins32 |= *(FAR uint16_t *)(pc - i + 2);
+      if (INSTR_IS(ins32, T_STMDB))
+        {
+          frame = __builtin_popcount(ins32 & 0xfff) + 1;
+          break;
+        }
+    }
+
+  if (i >= INSTR_LIMIT)
+    {
+      return NULL;
+    }
+
+  base = pc - i;
+
+  i = 0;
+
+  while (i < INSTR_LIMIT && base + i < pc)
+    {
+      ins16 = *(FAR uint16_t *)(base + i);
+      if (INSTR_IS(ins16, T_SUB_SP_16))
+        {
+          frame += (ins16 & 0x7f);
+          break;
+        }
+
+      ins32  = ins16 << 16;
+      ins32 |= *(FAR uint16_t *)(base + i + 2);
+      if (INSTR_IS(ins32, T_SUB_SP_32))
+        {
+          uint32_t shift;
+          uint32_t sub;
+
+          sub    = (ins32 & 0x7f) + 0x80;
+          shift  = (ins32 >> 7) & 0x1;
+          shift += ((ins32 >> 12) & 0x7) << 1;
+          shift += ((ins32 >> 26) & 0x1) << 4;
+
+          frame += sub << (30 - shift);
+          break;
+        }
+      else if (INSTR_IS(ins32, T_VPUSH_16))
+        {
+          frame += (ins32 & 0xff);
+        }
+      else if (INSTR_IS(ins32, T_VPUSH_8))
+        {
+          frame += (ins32 & 0xff) / 2;
+        }
+
+      i += ((ins16 & 0xf800) >= 0xe800) ? 4 : 2;
+    }
+
+  lr = (FAR uint8_t *)*((FAR uint32_t *)sp + frame - offset);
+  if (lr == NULL)
+    {
+      return NULL;
+    }
+
+  offset = getlroffset(lr);
+  if (offset == 0)
+    {
+      return NULL;
+    }
+
+  *psp   = (FAR uint32_t *)sp + frame;
+  *ppc   = lr - offset;
+
+  return *ppc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_backtrace

Review comment:
       ditto

##########
File path: arch/arm/src/arm/arm_backtrace.c
##########
@@ -0,0 +1,268 @@
+/****************************************************************************
+ * arch/arm/src/arm/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset

Review comment:
       Please include a complete Description of the function, including params and return

##########
File path: arch/arm/src/armv7-r/arm_backtrace.c
##########
@@ -0,0 +1,268 @@
+/****************************************************************************
+ * arch/arm/src/armv7-r/arm_backtrace.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/arch.h>
+
+#include "sched/sched.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Macro and definitions for simple decoding of instuctions.
+ * To check an instruction, it is ANDed with the IMASK_ and
+ * the result is compared with the IOP_. The macro INSTR_IS
+ * does this and returns !0 to indicate a match.
+ */
+
+#define INSTR_IS(i, o) (((i) & (IMASK_##o)) == (IOP_##o))
+
+#define IMASK_T_STMDB     0xfffff000  /* stmdb sp!,{..lr} */
+#define IOP_T_STMDB       0xe92d4000
+
+#define IMASK_T_PUSH_LO   0xff00      /* push {reglist} (not LR) */
+#define IOP_T_PUSH_LO     0xb400
+
+#define IMASK_T_PUSH      0xff00      /* push {reglist} (inc LR) */
+#define IOP_T_PUSH        0xb500
+
+#define IMASK_T_VPUSH_16  0xffbf8f00  /* vpush d */
+#define IOP_T_VPUSH_16    0xed2d8b00
+
+#define IMASK_T_VPUSH_8   0xffbf8f00  /* vpush s */
+#define IOP_T_VPUSH_8     0xed2d8a00
+
+#define IMASK_T_SUB_SP_16 0xff80      /* sub sp, # */
+#define IOP_T_SUB_SP_16   0xb080
+
+#define IMASK_T_SUB_SP_32 0xfbff8f00  /* sub.w sp, sp, # */
+#define IOP_T_SUB_SP_32   0xf1ad0d00
+
+#define INSTR_LIMIT       0x2000
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: getlroffset
+ ****************************************************************************/
+
+static int getlroffset(FAR uint8_t *lr)
+{
+  lr = (FAR uint8_t *)((uintptr_t)lr & 0xfffffffe);
+
+  if (((uintptr_t)lr & 0xffffffe0) == 0xffffffe0)
+    {
+      return 0;
+    }
+
+  return (*(FAR uint16_t *)(lr - 4) & 0xf000) == 0xf000 ? 5 : 3;
+}
+
+/****************************************************************************
+ * Name: backtrace_internal
+ ****************************************************************************/
+
+static FAR void *backtrace_internal(FAR void **psp, FAR void **ppc,
+                                    FAR void *addr)
+{
+  FAR uint8_t *sp = *psp;
+  FAR uint8_t *pc = *ppc;
+  FAR uint8_t *base;
+  FAR uint8_t *lr;
+  uint32_t ins32;
+  uint16_t ins16;
+  int offset;
+  int frame;
+  int i;
+
+  if (*psp >= addr)
+    {
+      return NULL;
+    }
+
+  offset = 1;
+
+  for (i = 2; i < INSTR_LIMIT; i += 2)
+    {
+      ins16 = *(FAR uint16_t *)(pc - i);
+      if (INSTR_IS(ins16, T_PUSH))
+        {
+          frame = __builtin_popcount(ins16 & 0xff) + 1;
+          ins16 = *(FAR uint16_t *)(pc - i - 2);
+          if (INSTR_IS(ins16, T_PUSH_LO))
+            {
+              offset = __builtin_popcount(ins16 & 0xff);
+              frame += offset;
+            }
+
+          break;
+        }
+
+      ins32  = ins16 << 16;
+      ins32 |= *(FAR uint16_t *)(pc - i + 2);
+      if (INSTR_IS(ins32, T_STMDB))
+        {
+          frame = __builtin_popcount(ins32 & 0xfff) + 1;
+          break;
+        }
+    }
+
+  if (i >= INSTR_LIMIT)
+    {
+      return NULL;
+    }
+
+  base = pc - i;
+
+  i = 0;
+
+  while (i < INSTR_LIMIT && base + i < pc)
+    {
+      ins16 = *(FAR uint16_t *)(base + i);
+      if (INSTR_IS(ins16, T_SUB_SP_16))
+        {
+          frame += (ins16 & 0x7f);
+          break;
+        }
+
+      ins32  = ins16 << 16;
+      ins32 |= *(FAR uint16_t *)(base + i + 2);
+      if (INSTR_IS(ins32, T_SUB_SP_32))
+        {
+          uint32_t shift;
+          uint32_t sub;
+
+          sub    = (ins32 & 0x7f) + 0x80;
+          shift  = (ins32 >> 7) & 0x1;
+          shift += ((ins32 >> 12) & 0x7) << 1;
+          shift += ((ins32 >> 26) & 0x1) << 4;
+
+          frame += sub << (30 - shift);
+          break;
+        }
+      else if (INSTR_IS(ins32, T_VPUSH_16))
+        {
+          frame += (ins32 & 0xff);
+        }
+      else if (INSTR_IS(ins32, T_VPUSH_8))
+        {
+          frame += (ins32 & 0xff) / 2;
+        }
+
+      i += ((ins16 & 0xf800) >= 0xe800) ? 4 : 2;
+    }
+
+  lr = (FAR uint8_t *)*((FAR uint32_t *)sp + frame - offset);
+  if (lr == NULL)
+    {
+      return NULL;
+    }
+
+  offset = getlroffset(lr);
+  if (offset == 0)
+    {
+      return NULL;
+    }
+
+  *psp   = (FAR uint32_t *)sp + frame;
+  *ppc   = lr - offset;
+
+  return *ppc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_backtrace

Review comment:
       ditto




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [incubator-nuttx] xiaoxiang781216 commented on pull request #4259: sched/backtrace: add support for printing the arbitrary thread backtrace in runtime

Posted by GitBox <gi...@apache.org>.
xiaoxiang781216 commented on pull request #4259:
URL: https://github.com/apache/incubator-nuttx/pull/4259#issuecomment-889669037


   Look good, please create a new patch to incoperate xtensa bracktrace to the new interface.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org