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: 100.0 % 67 67
Test Date: 2026-08-31 10:07:06 Functions: 100.0 % 12 12

            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           18 : STATIC TraStatus ScdThreadWaitTidStopped(int32_t tid)
      17              : {
      18              :     int32_t status;
      19              :     int32_t ret;
      20              :     do {
      21           26 :         ret = SCD_UTIL_RETRY(waitpid(tid, &status, __WALL));
      22           22 :         if (ret == -1) {
      23            4 :             SCD_DLOG_WAR("can not watipid, tid=%d, errno=%d", tid, errno);
      24            4 :             return TRACE_FAILURE;
      25              :         }
      26           18 :         if (!WIFSTOPPED(status)) {
      27            4 :             SCD_DLOG_WAR("can not stop thread, tid=%d, status=%x", tid, status);
      28            4 :             return TRACE_FAILURE;
      29              :         }
      30           14 :         if (WSTOPSIG(status) == SIGSTOP) {
      31           10 :             break;
      32              :         }
      33            4 :         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            4 :         ScdPtraceContinue(tid);
      36              :     } while (true);
      37           10 :     return TRACE_SUCCESS;
      38              : }
      39              : 
      40           22 : TraStatus ScdThreadSuspend(ScdThread* thd)
      41              : {
      42           22 :     int32_t tid = thd->tid;
      43           22 :     if (ScdPtraceAttach(tid) != TRACE_SUCCESS) {
      44            4 :         SCD_DLOG_WAR("can not ptrace ATTACH, tid=%d, errno=%d", tid, errno);
      45            4 :         thd->status = SCD_THREAD_STATUS_ATTACH;
      46            4 :         return TRACE_FAILURE;
      47              :     }
      48           18 :     return ScdThreadWaitTidStopped(tid);
      49              : }
      50              : 
      51            6 : void ScdThreadResume(ScdThread* thd) { ScdPtraceDetach(thd->tid); }
      52              : 
      53           14 : STATIC void ScdThreadGetName(ScdThread* thd)
      54              : {
      55           14 :     ScdUtilGetThreadName(thd->pid, thd->tid, thd->tname, SCD_THREAD_NAME_LEN);
      56           14 : }
      57              : 
      58            8 : STATIC TraStatus ScdThreadGetRegs(ScdThread* thd)
      59              : {
      60            8 :     uintptr_t regBuf[SCD_REGS_NUM] = {0};
      61              :     // 通过ptrace获取
      62            8 :     if (ScdPtraceGetRegs(thd->tid, regBuf, SCD_REGS_NUM) != TRACE_SUCCESS) {
      63            4 :         thd->status = SCD_THREAD_STATUS_REGS;
      64            4 :         return TRACE_FAILURE;
      65              :     }
      66            4 :     GET_REGISTER_FROM_PTRACE(thd->regs.r, regBuf);
      67            4 :     return TRACE_SUCCESS;
      68              : }
      69              : 
      70            8 : TraStatus ScdThreadLoadInfo(ScdThread* thd)
      71              : {
      72            8 :     ScdThreadGetName(thd);
      73            8 :     TraStatus ret = ScdThreadGetRegs(thd);
      74            8 :     if (ret != TRACE_SUCCESS) {
      75            4 :         SCD_DLOG_WAR("can not ptrace get regs, tid=%d, errno=%d", thd->tid, errno);
      76            4 :         return TRACE_FAILURE;
      77              :     }
      78            4 :     return TRACE_SUCCESS;
      79              : }
      80              : 
      81            6 : TraStatus ScdThreadLoadInfoForCrash(ScdThread* thd, ScdRegs* regs)
      82              : {
      83            6 :     ScdThreadGetName(thd);
      84            6 :     errno_t ret = memcpy_s(&thd->regs, sizeof(ScdRegs), regs, sizeof(ScdRegs));
      85            6 :     if (ret != EOK) {
      86            4 :         SCD_DLOG_WAR("can not memcpy_s, ret=%d, errno=%d", (int32_t)ret, errno);
      87            4 :         return TRACE_FAILURE;
      88              :     }
      89            2 :     SCD_DLOG_DBG(
      90              :         "set crash thread info, tid=%d, pc=0x%lx, sp=0x%lx, fp=0x%lx.", thd->tid, GET_PCREG(regs->r),
      91              :         GET_SPREG(regs->r), GET_FPREG(regs->r));
      92            2 :     return TRACE_SUCCESS;
      93              : }
      94              : 
      95           27 : TraStatus ScdThreadLoadFrames(ScdThread* thd, ScdMaps* maps) { return ScdFramesLoad(&thd->frames, maps, &thd->regs); }
      96              : 
      97           34 : STATIC TraStatus ScdThreadInit(ScdThread* thd, int32_t pid, int32_t tid)
      98              : {
      99           34 :     SCD_CHK_PTR_ACTION(thd, return TRACE_FAILURE);
     100           34 :     thd->status = SCD_THREAD_STATUS_INIT;
     101           34 :     thd->pid = pid;
     102           34 :     thd->tid = tid;
     103           34 :     (void)memset_s(&(thd->regs), sizeof(thd->regs), 0, sizeof(thd->regs));
     104           34 :     return ScdFramesInit(&thd->frames, pid, tid);
     105              : }
     106              : 
     107           30 : STATIC void ScdThreadUninit(ScdThread* thd) { ScdFramesUninit(&thd->frames); }
     108              : 
     109           34 : ScdThread* ScdThreadCreate(int32_t pid, int32_t tid)
     110              : {
     111           34 :     ScdThread* thd = AdiagMalloc(sizeof(ScdThread));
     112           34 :     if (thd != NULL) {
     113           34 :         TraStatus ret = ScdThreadInit(thd, pid, tid);
     114           34 :         if (ret != TRACE_SUCCESS) {
     115            4 :             ADIAG_SAFE_FREE(thd);
     116              :         }
     117              :     }
     118           34 :     return thd;
     119              : }
     120              : 
     121           34 : void ScdThreadDestroy(ScdThread** thd)
     122              : {
     123           34 :     if ((thd != NULL) && (*thd != NULL)) {
     124           30 :         ScdThreadUninit(*thd);
     125           30 :         ADIAG_SAFE_FREE(*thd);
     126              :     }
     127           34 : }
        

Generated by: LCOV version 2.0-1