LCOV - code coverage report
Current view: top level - atrace/utrace/stacktrace/stacktrace_dumper - scd_thread.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 31.9 % 72 23
Test Date: 2026-07-28 10:53:44 Functions: 41.7 % 12 5

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "scd_thread.h"
      12              : #include "adiag_utils.h"
      13              : #include "scd_log.h"
      14              : #include "scd_ptrace.h"
      15              : 
      16            0 : STATIC TraStatus ScdThreadWaitTidStopped(int32_t tid)
      17              : {
      18              :     int32_t status;
      19              :     int32_t ret;
      20              :     do {
      21            0 :         ret = SCD_UTIL_RETRY(waitpid(tid, &status, __WALL));
      22            0 :         if (ret == -1) {
      23            0 :             SCD_DLOG_WAR("can not watipid, tid=%d, errno=%d", tid, errno);
      24            0 :             return TRACE_FAILURE;
      25              :         }
      26            0 :         if (!WIFSTOPPED(status)) {
      27            0 :             SCD_DLOG_WAR("can not stop thread, tid=%d, status=%x", tid, status);
      28            0 :             return TRACE_FAILURE;
      29              :         }
      30            0 :         if (WSTOPSIG (status) == SIGSTOP) {
      31            0 :             break;
      32              :         }
      33            0 :         SCD_DLOG_WAR("waitpid ret = %d, status=%x, tid=%d", ret, status, tid);
      34              :         // receive other signal, continue with no signal to still wait for SIGSTOP
      35            0 :         ScdPtraceContinue(tid);
      36              :     } while (true);
      37            0 :     return TRACE_SUCCESS;
      38              : }
      39              : 
      40            0 : TraStatus ScdThreadSuspend(ScdThread *thd)
      41              : {
      42            0 :     int32_t tid = thd->tid;
      43            0 :     if (ScdPtraceAttach(tid) != TRACE_SUCCESS) {
      44            0 :         SCD_DLOG_WAR("can not ptrace ATTACH, tid=%d, errno=%d", tid, errno);
      45            0 :         thd->status = SCD_THREAD_STATUS_ATTACH;
      46            0 :         return TRACE_FAILURE;
      47              :     }
      48            0 :     return ScdThreadWaitTidStopped(tid);
      49              : }
      50              : 
      51            0 : void ScdThreadResume(ScdThread *thd)
      52              : {
      53            0 :     ScdPtraceDetach(thd->tid);
      54            0 : }
      55              : 
      56            0 : STATIC void ScdThreadGetName(ScdThread *thd)
      57              : {
      58            0 :     ScdUtilGetThreadName(thd->pid, thd->tid, thd->tname, SCD_THREAD_NAME_LEN);
      59            0 : }
      60              : 
      61            0 : STATIC TraStatus ScdThreadGetRegs(ScdThread *thd)
      62              : {
      63            0 :     uintptr_t regBuf[SCD_REGS_NUM] = {0};
      64              :     // 通过ptrace获取
      65            0 :     if (ScdPtraceGetRegs(thd->tid, regBuf, SCD_REGS_NUM) != TRACE_SUCCESS) {
      66            0 :         thd->status = SCD_THREAD_STATUS_REGS;
      67            0 :         return TRACE_FAILURE;
      68              :     }
      69            0 :     GET_REGISTER_FROM_PTRACE(thd->regs.r, regBuf);
      70            0 :     return TRACE_SUCCESS;
      71              : }
      72              : 
      73            0 : TraStatus ScdThreadLoadInfo(ScdThread *thd)
      74              : {
      75            0 :     ScdThreadGetName(thd);
      76            0 :     TraStatus ret = ScdThreadGetRegs(thd);
      77            0 :     if (ret != TRACE_SUCCESS) {
      78            0 :         SCD_DLOG_WAR("can not ptrace get regs, tid=%d, errno=%d", thd->tid, errno);
      79            0 :         return TRACE_FAILURE;
      80              :     }
      81            0 :     return TRACE_SUCCESS;
      82              : }
      83              : 
      84            0 : TraStatus ScdThreadLoadInfoForCrash(ScdThread *thd, ScdRegs *regs)
      85              : {
      86            0 :     ScdThreadGetName(thd);
      87            0 :     errno_t ret = memcpy_s(&thd->regs, sizeof(ScdRegs), regs, sizeof(ScdRegs));
      88            0 :     if (ret != EOK) {
      89            0 :         SCD_DLOG_WAR("can not memcpy_s, ret=%d, errno=%d", (int32_t)ret, errno);
      90            0 :         return TRACE_FAILURE;
      91              :     }
      92            0 :     SCD_DLOG_DBG("set crash thread info, tid=%d, pc=0x%lx, sp=0x%lx, fp=0x%lx.",
      93              :         thd->tid, GET_PCREG(regs->r), GET_SPREG(regs->r), GET_FPREG(regs->r));
      94            0 :     return TRACE_SUCCESS;
      95              : }
      96              : 
      97           15 : TraStatus ScdThreadLoadFrames(ScdThread *thd, ScdMaps *maps)
      98              : {
      99           15 :     return ScdFramesLoad(&thd->frames, maps, &thd->regs);
     100              : }
     101              : 
     102           15 : STATIC TraStatus ScdThreadInit(ScdThread *thd, int32_t pid, int32_t tid)
     103              : {
     104           15 :     SCD_CHK_PTR_ACTION(thd, return TRACE_FAILURE);
     105           15 :     thd->status = SCD_THREAD_STATUS_INIT;
     106           15 :     thd->pid = pid;
     107           15 :     thd->tid = tid;
     108           15 :     (void)memset_s(&(thd->regs), sizeof(thd->regs), 0, sizeof(thd->regs));
     109           15 :     return ScdFramesInit(&thd->frames, pid, tid);
     110              : }
     111              : 
     112           15 : STATIC void ScdThreadUninit(ScdThread *thd)
     113              : {
     114           15 :     ScdFramesUninit(&thd->frames);
     115           15 : }
     116              : 
     117           15 : ScdThread *ScdThreadCreate(int32_t pid, int32_t tid)
     118              : {
     119           15 :     ScdThread *thd = AdiagMalloc(sizeof(ScdThread)); 
     120           15 :     if (thd != NULL) {
     121           15 :         TraStatus ret = ScdThreadInit(thd, pid, tid);
     122           15 :         if (ret != TRACE_SUCCESS) {
     123            0 :             ADIAG_SAFE_FREE(thd);
     124              :         }
     125              :     }
     126           15 :     return thd;
     127              : }
     128              : 
     129           15 : void ScdThreadDestroy(ScdThread **thd)
     130              : {
     131           15 :     if ((thd != NULL) && (*thd != NULL)) {
     132           15 :         ScdThreadUninit(*thd);
     133           15 :         ADIAG_SAFE_FREE(*thd);
     134              :     }
     135           15 : }
        

Generated by: LCOV version 2.0-1