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: 98.7 % 77 76
Test Date: 2026-08-31 10:07:06 Functions: 100.0 % 9 9

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

Generated by: LCOV version 2.0-1