LCOV - code coverage report
Current view: top level - atrace/utrace/stacktrace/stacktrace_dumper - scd_maps.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 88.5 % 78 69
Test Date: 2026-07-28 10:53:44 Functions: 77.8 % 9 7

            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_maps.h"
      12              : #include "scd_map.h"
      13              : #include "scd_log.h"
      14              : #include "adiag_list.h"
      15              : #include "scd_util.h"
      16              : #include "atrace_types.h"
      17              : #include "trace_system_api.h"
      18              : 
      19              : #define SCD_MAPS_BUF_LEN     512U
      20              : 
      21              : STATIC ScdMaps g_maps;
      22              : 
      23           80 : ScdMaps *ScdMapsGet(void)
      24              : {
      25           80 :     return &g_maps;
      26              : }
      27              : 
      28        29600 : STATIC TraStatus ScdMapsCmpName(const void *nodeData, const void *data)
      29              : {
      30        29600 :     const ScdMap *node = (const ScdMap *)nodeData;
      31        29600 :     const char *name = (const char *)data;
      32        29600 :     if (strcmp(node->name, name) == 0) {
      33         5280 :         return TRACE_SUCCESS;
      34              :     }
      35        24320 :     return TRACE_FAILURE;
      36              : }
      37              : 
      38         6192 : STATIC ScdMap *ScdMapsGetMapByName(ScdMaps *maps, const char *name)
      39              : {
      40         6192 :     return AdiagListForEach(&maps->mapList, ScdMapsCmpName, name);
      41              : }
      42              : 
      43            0 : STATIC TraStatus ScdMapsCmpPcRange(const void *nodeData, const void *data)
      44              : {
      45            0 :     const ScdMap *node = (const ScdMap *)nodeData;
      46            0 :     uintptr_t pc = (uintptr_t)data;
      47            0 :     if (pc >= node->start && pc < node->end) {
      48            0 :         return TRACE_SUCCESS;
      49              :     }
      50            0 :     return TRACE_FAILURE;
      51              : }
      52              : 
      53            0 : ScdMap *ScdMapsGetMapByPc(ScdMaps *maps, uintptr_t pc)
      54              : {
      55            0 :     return AdiagListForEach(&maps->mapList, ScdMapsCmpPcRange, (const void *)pc);
      56              : }
      57              : 
      58        10386 : STATIC ScdMap *ScdMapsParseLine(ScdMaps *maps, char *line, uint32_t len)
      59              : {
      60        10386 :     uintptr_t start = 0;
      61        10386 :     uintptr_t end = 0;
      62        10386 :     size_t offset = 0;
      63        10386 :     int32_t pos = 0;
      64              : 
      65              :     // scan
      66        10386 :     int32_t ret = sscanf_s(line, "%lx-%lx %*s %lx %*x:%*x %*d%n", &start, &end, &offset, &pos);
      67        10386 :     if ((ret <= 0) || (pos >= (int32_t)len) || (pos <= 0)) {
      68         2016 :         SCD_DLOG_ERR("sscanf_s failed, ret = %d, line = %s.", ret, line);
      69         2016 :         return NULL;
      70              :     }
      71              : 
      72         8370 :     const char *name = NULL;
      73         8370 :     if (ScdUtilTrim(line + pos, len - (uint32_t)pos, &name) != TRACE_SUCCESS) {
      74            0 :         return NULL;
      75              :     }
      76         8370 :     if ((name == NULL) || (strlen(name) == 0)) {
      77         2080 :         return NULL;
      78              :     }
      79         6290 :     char realPath[TRACE_MAX_PATH] = { 0 };
      80         6290 :     errno = 0;
      81         6290 :     if ((TraceRealPath(name, realPath, TRACE_MAX_PATH) != EN_OK) && (errno != ENOENT)) {
      82           98 :         SCD_DLOG_ERR("can not get realpath, path=%s, strerr=%s.", name, strerror(errno));
      83           98 :         return NULL;
      84              :     }
      85              : 
      86              :     // find map
      87         6192 :     ScdMap *map = ScdMapsGetMapByName(maps, realPath);
      88         6192 :     if (map != NULL) {
      89              :         // the start and end of the multi-segment code segment of the map are updated each time
      90         5280 :         if (ScdMapUpdata(map, start, end, offset) == TRACE_SUCCESS) {
      91         5280 :             return NULL;
      92              :         }
      93              :     }
      94              :     // create map
      95          912 :     return ScdMapCreate(start, end, offset, realPath);
      96              : }
      97              : 
      98              : /**
      99              :  * @brief       load maps
     100              :  * @param [in]  maps:       maps info
     101              :  * @return      TraStatus
     102              :  */
     103          129 : TraStatus ScdMapsLoad(ScdMaps *maps)
     104              : {
     105          129 :     char buf[SCD_MAPS_BUF_LEN] = {0};
     106          129 :     int32_t err = snprintf_s(buf, SCD_MAPS_BUF_LEN, SCD_MAPS_BUF_LEN - 1U, "/proc/%d/maps", maps->pid);
     107          129 :     if (err == -1) {
     108           16 :         SCD_DLOG_ERR("snprintf_s failed, get maps file name failed.");
     109           16 :         return TRACE_FAILURE;
     110              :     }
     111              : 
     112          113 :     FILE *fp = fopen(buf, "r");
     113          113 :     if (fp == NULL) {
     114           16 :         SCD_DLOG_ERR("open maps file failed.");
     115           16 :         return TRACE_FAILURE;
     116              :     }
     117              : 
     118        10467 :     while (fgets(buf, SCD_MAPS_BUF_LEN, fp) != NULL) {
     119        10386 :         ScdMap *node = ScdMapsParseLine(maps, buf, SCD_MAPS_BUF_LEN);
     120        10386 :         if (node == NULL) {
     121         9474 :             continue;
     122              :         }
     123              : 
     124          912 :         AdiagStatus ret = AdiagListInsert(&maps->mapList, node);
     125          912 :         if (ret != ADIAG_SUCCESS) {
     126           16 :             SCD_DLOG_ERR("add map to map list failed.");
     127           16 :             ScdMapDestroy(&node);
     128           16 :             (void)fclose(fp);
     129           16 :             return TRACE_FAILURE;
     130              :         }
     131              :     }
     132              : 
     133           81 :     (void)fclose(fp);
     134           81 :     return TRACE_SUCCESS;
     135              : }
     136              : 
     137              : /**
     138              :  * @brief       init maps
     139              :  * @param [in]  maps:       maps info
     140              :  * @param [in]  pid:        process id
     141              :  * @return      TraStatus
     142              :  */
     143          370 : TraStatus ScdMapsInit(ScdMaps *maps, int32_t pid)
     144              : {
     145          370 :     SCD_CHK_PTR_ACTION(maps, return TRACE_FAILURE);
     146              : 
     147          370 :     maps->pid = pid;
     148          370 :     AdiagStatus adiagRet = AdiagListInit(&maps->mapList);
     149          370 :     if (adiagRet != ADIAG_SUCCESS) {
     150           16 :         SCD_DLOG_ERR("init maps list failed.");
     151           16 :         return TRACE_FAILURE;
     152              :     }
     153          354 :     return TRACE_SUCCESS;
     154              : }
     155              : 
     156              : /**
     157              :  * @brief       init maps
     158              :  * @param [in]  maps:       maps info
     159              :  * @return      NA
     160              :  */
     161          354 : void ScdMapsUninit(ScdMaps *maps)
     162              : {
     163          354 :     ScdMap *node = (ScdMap *)AdiagListTakeOut(&maps->mapList);
     164         1250 :     while (node != NULL) {
     165          896 :         ScdMapDestroy(&node);
     166          896 :         node = (ScdMap *)AdiagListTakeOut(&maps->mapList);
     167              :     }
     168          354 : }
        

Generated by: LCOV version 2.0-1