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 "stacktrace_safe_recorder.h"
12 : #include <errno.h>
13 : #include "securec.h"
14 : #include "stacktrace_logger.h"
15 : #include "stacktrace_file_struct.h"
16 : #include "trace_recorder.h"
17 : #include "trace_system_api.h"
18 : #include "trace_types.h"
19 : #include "adiag_utils.h"
20 : #include "adiag_print.h"
21 :
22 : #define PROCESS_SECTION "[process]\n"
23 : #define STACK_SECTION "[stack]\n"
24 : #define MAPS_SECTION "[maps]\n"
25 : #define MEMORY_SECTION "[system memory]\n"
26 : #define STATUS_SECTION "[process status]\n"
27 : #define LIMITS_SECTION "[process limits]\n"
28 :
29 : #define PROC_MEMINFO_PATH "/proc/meminfo"
30 :
31 : STATIC TraceStackInfo g_stackInfo = {0};
32 : STATIC struct StackcoreBuffer g_stackBuff = {0};
33 :
34 : /**
35 : * @brief read a line data from file
36 : * @param [in] fd: file descriptor
37 : * @param [in] data: write data
38 : * @param [in] len: data buffer length
39 : * @return >0 success; -1 failed
40 : */
41 42030 : ssize_t TraceSafeReadLine(int32_t fd, char* data, uint32_t len)
42 : {
43 42030 : if (fd < 0 || data == NULL || len == 0) {
44 22 : return -1;
45 : }
46 :
47 42008 : ssize_t n = 1;
48 42008 : char c = (char)EOF;
49 42008 : char* ptr = data;
50 3172145 : while (n < (ssize_t)len) {
51 3172018 : ssize_t rc = read(fd, &c, 1);
52 3172018 : if (rc == 1) {
53 3171343 : *ptr = c;
54 3171343 : ptr++;
55 3171343 : if (c == '\n') {
56 41228 : break;
57 : }
58 675 : } else if (rc == 0) {
59 631 : *ptr = '\0';
60 631 : return (n - 1);
61 : } else {
62 44 : if (errno == EINTR) {
63 22 : continue;
64 : }
65 22 : return -1;
66 : }
67 3130115 : n++;
68 : }
69 41355 : *ptr = '\0';
70 41355 : return n;
71 : }
72 :
73 : /**
74 : * @brief safe write data to file
75 : * @param [in] fd: file descriptor
76 : * @param [in] data: write data
77 : * @param [in] len: data buffer length
78 : * @return TraStatus
79 : */
80 31777 : STATIC TraStatus TraceSafeWrite(int32_t fd, const char* data, size_t len)
81 : {
82 31777 : if ((fd < 0) || (data == NULL) || (len == 0)) {
83 88 : return TRACE_INVALID_PARAM;
84 : }
85 :
86 31689 : size_t reserved = len;
87 : do {
88 31711 : ssize_t wrLen = write(fd, data + (len - reserved), reserved);
89 31711 : if (wrLen < 0 && errno == EINTR) {
90 22 : wrLen = 0;
91 31689 : } else if (wrLen < 0) {
92 44 : return TRACE_FAILURE;
93 : } else {
94 : ;
95 : }
96 31667 : reserved -= (size_t)wrLen;
97 31667 : } while (reserved != 0);
98 31645 : return TRACE_SUCCESS;
99 : }
100 :
101 0 : const char* TraceSafeGetFilePath(void) { return TraceRecorderSafeGetFilePath(); }
102 :
103 : /**
104 : * @brief get fd to write stackcore file
105 : use for signal_callback_func, only call reentrant function
106 : * @param [in] info: info, for dir name and file name
107 : * @param [in] suffix: file suffix
108 : * @param [out] fd: file handle
109 : * @return TraStatus
110 : */
111 237 : TraStatus TraceSafeGetFd(const TraceStackRecorderInfo* info, const char* suffix, int32_t* fd)
112 : {
113 237 : if ((info == NULL) || (fd == NULL)) {
114 22 : return TRACE_INVALID_PARAM;
115 : }
116 :
117 215 : char timeString[TIMESTAMP_MAX_LENGTH] = {0};
118 215 : uint64_t fileTime = GetRealTime();
119 215 : TraStatus ret = TimestampToFileStr(fileTime, timeString, TIMESTAMP_MAX_LENGTH);
120 215 : if (ret != TRACE_SUCCESS) {
121 22 : return ret;
122 : }
123 193 : char objName[MAX_FILEPATH_LEN] = {0};
124 193 : int32_t err = snprintf_s(
125 193 : objName, MAX_FILEPATH_LEN, MAX_FILEPATH_LEN - 1U, "%d_%d_%s_%s", info->signo, info->tid,
126 : program_invocation_short_name, timeString);
127 193 : if (err == -1) {
128 0 : return TRACE_FAILURE;
129 : }
130 :
131 : // get dir time by crash time
132 193 : ret = TimestampToFileStr(info->crashTime, timeString, TIMESTAMP_MAX_LENGTH);
133 193 : if (ret != TRACE_SUCCESS) {
134 22 : return ret;
135 : }
136 :
137 171 : g_stackBuff.head.magic = STACK_HEAD_MAGIC;
138 171 : g_stackBuff.head.version = STACK_HEAD_VERSION;
139 171 : TraceDirInfo dirInfo = {TRACER_STACKCORE_NAME, info->pid, timeString, false};
140 171 : TraceFileInfo fileInfo = {TRACER_STACKCORE_NAME, objName, suffix};
141 171 : return TraceRecorderSafeGetFd(&dirInfo, &fileInfo, fd);
142 : }
143 :
144 215 : TraceStackInfo* TraceSafeGetStackBuffer(void) { return &g_stackInfo; }
145 :
146 : /**
147 : * @brief write "system memory" info
148 : * @param [in] fd: handle of stack core file
149 : * @return TraStatus
150 : */
151 281 : STATIC TraStatus TraceSafeWriteMemoryInfo(int32_t fd)
152 : {
153 : // write title [system memory]
154 281 : TraStatus ret = TraceSafeWrite(fd, MEMORY_SECTION, strlen(MEMORY_SECTION));
155 281 : if (ret != TRACE_SUCCESS) {
156 44 : LOGE("write memory title failed, ret=%d, errno=%d", ret, errno);
157 44 : return ret;
158 : }
159 :
160 : // write memory info
161 237 : int32_t memFd = open(PROC_MEMINFO_PATH, O_RDONLY);
162 237 : if (memFd < 0) {
163 22 : LOGE("memory info file open failed, errno=%d", errno);
164 22 : return TRACE_FAILURE;
165 : }
166 :
167 215 : char info[CORE_BUFFER_LEN] = {0};
168 10058 : while (TraceSafeReadLine(memFd, info, CORE_BUFFER_LEN) > 0) {
169 9865 : ret = TraceSafeWrite(fd, info, strlen(info));
170 9865 : if (ret != TRACE_SUCCESS) {
171 22 : LOGE("write memory info to file failed, ret=%d, errno=%d", ret, errno);
172 22 : TraceClose(&memFd);
173 22 : return ret;
174 : }
175 : }
176 193 : TraceClose(&memFd);
177 193 : (void)TraceSafeWrite(fd, "\n", 1);
178 193 : return TRACE_SUCCESS;
179 : }
180 :
181 : /**
182 : * @brief write "process status" info
183 : * @param [in] fd: handle of stack core file
184 : * @param [in] pid: process id
185 : * @return TraStatus
186 : */
187 303 : STATIC TraStatus TraceSafeWriteStatusInfo(int32_t fd, int32_t pid)
188 : {
189 : // write title [process status]
190 303 : TraStatus ret = TraceSafeWrite(fd, STATUS_SECTION, strlen(STATUS_SECTION));
191 303 : if (ret != TRACE_SUCCESS) {
192 44 : LOGE("write status title failed, ret=%d, errno=%d", ret, errno);
193 44 : return ret;
194 : }
195 259 : char path[CORE_BUFFER_LEN] = {0};
196 259 : int32_t err = snprintf_s(path, CORE_BUFFER_LEN, CORE_BUFFER_LEN - 1U, "/proc/%d/status", pid);
197 259 : if (err == -1) {
198 22 : LOGE("snprintf_s status path failed");
199 22 : return TRACE_FAILURE;
200 : }
201 : // write status info
202 237 : int32_t statFd = open(path, O_RDONLY);
203 237 : if (statFd < 0) {
204 88 : LOGE("status file open failed, errno=%d", errno);
205 88 : return TRACE_FAILURE;
206 : }
207 :
208 149 : char info[CORE_BUFFER_LEN] = {0};
209 7388 : while (TraceSafeReadLine(statFd, info, CORE_BUFFER_LEN) > 0) {
210 7261 : ret = TraceSafeWrite(fd, info, strlen(info));
211 7261 : if (ret != TRACE_SUCCESS) {
212 22 : LOGE("write status info to file failed, ret=%d, errno=%d", ret, errno);
213 22 : TraceClose(&statFd);
214 22 : return ret;
215 : }
216 : }
217 127 : TraceClose(&statFd);
218 127 : (void)TraceSafeWrite(fd, "\n", 1);
219 127 : return TRACE_SUCCESS;
220 : }
221 :
222 : /**
223 : * @brief write "process limits" info
224 : * @param [in] fd: handle of stack core file
225 : * @param [in] pid: process id
226 : * @return TraStatus
227 : */
228 303 : STATIC TraStatus TraceSafeWriteLimitsInfo(int32_t fd, int32_t pid)
229 : {
230 : // write title [process limits]
231 303 : TraStatus ret = TraceSafeWrite(fd, LIMITS_SECTION, strlen(LIMITS_SECTION));
232 303 : if (ret != TRACE_SUCCESS) {
233 44 : LOGE("write limits title failed, ret=%d, errno=%d", ret, errno);
234 44 : return ret;
235 : }
236 259 : char path[CORE_BUFFER_LEN] = {0};
237 259 : int32_t err = snprintf_s(path, CORE_BUFFER_LEN, CORE_BUFFER_LEN - 1U, "/proc/%d/limits", pid);
238 259 : if (err == -1) {
239 22 : LOGE("snprintf_s limits path failed");
240 22 : return TRACE_FAILURE;
241 : }
242 : // write limits info
243 237 : int32_t limitsFd = open(path, O_RDONLY);
244 237 : if (limitsFd < 0) {
245 88 : LOGE("limits file open failed, errno=%d", errno);
246 88 : return TRACE_FAILURE;
247 : }
248 :
249 149 : char info[CORE_BUFFER_LEN] = {0};
250 2308 : while (TraceSafeReadLine(limitsFd, info, CORE_BUFFER_LEN) > 0) {
251 2181 : ret = TraceSafeWrite(fd, info, strlen(info));
252 2181 : if (ret != TRACE_SUCCESS) {
253 22 : LOGE("write limits info to file failed, ret=%d, errno=%d", ret, errno);
254 22 : TraceClose(&limitsFd);
255 22 : return ret;
256 : }
257 : }
258 127 : TraceClose(&limitsFd);
259 127 : (void)TraceSafeWrite(fd, "\n", 1);
260 127 : return TRACE_SUCCESS;
261 : }
262 :
263 : /**
264 : * @brief write "maps" info
265 : * @param [in] fd: handle of stack core file
266 : * @param [in] pid: process id
267 : * @return TraStatus
268 : */
269 303 : STATIC TraStatus TraceSafeWriteMapsInfo(int32_t fd, int32_t pid)
270 : {
271 : // write title [maps]
272 303 : TraStatus ret = TraceSafeWrite(fd, MAPS_SECTION, strlen(MAPS_SECTION));
273 303 : if (ret != TRACE_SUCCESS) {
274 44 : LOGE("write maps title failed, ret=%d, errno=%d", ret, errno);
275 44 : return ret;
276 : }
277 :
278 259 : char path[CORE_BUFFER_LEN] = {0};
279 259 : int32_t err = snprintf_s(path, CORE_BUFFER_LEN, CORE_BUFFER_LEN - 1U, "/proc/%d/maps", pid);
280 259 : if (err == -1) {
281 22 : LOGE("snprintf_s maps path failed");
282 22 : return TRACE_FAILURE;
283 : }
284 : // write maps info
285 237 : int32_t mapFd = open(path, O_RDONLY);
286 237 : if (mapFd < 0) {
287 88 : LOGE("self map open failed, errno=%d", errno);
288 88 : return TRACE_FAILURE;
289 : }
290 :
291 149 : char info[CORE_BUFFER_LEN] = {0};
292 9636 : while (TraceSafeReadLine(mapFd, info, CORE_BUFFER_LEN) > 0) {
293 9531 : ret = TraceSafeWrite(fd, info, strlen(info));
294 9531 : if (ret != TRACE_SUCCESS) {
295 44 : LOGE("write maps info to file failed, ret=%d, errno=%d", ret, errno);
296 44 : TraceClose(&mapFd);
297 44 : return ret;
298 : }
299 : }
300 105 : TraceClose(&mapFd);
301 105 : (void)TraceSafeWrite(fd, "\n", 1);
302 105 : return TRACE_SUCCESS;
303 : }
304 :
305 : /**
306 : * @brief write "system memory" info
307 : * @param [in] fd: handle of stack core file
308 : * @param [in] pid: process id
309 : * @return TraStatus
310 : */
311 237 : TraStatus TraceSafeWriteSystemInfo(int32_t fd, int32_t pid)
312 : {
313 237 : TraStatus ret = TraceSafeWriteMapsInfo(fd, pid);
314 237 : if (ret != TRACE_SUCCESS) {
315 132 : LOGW("can not write maps info to file, ret=%d.", ret);
316 : }
317 :
318 237 : ret = TraceSafeWriteMemoryInfo(fd);
319 237 : if (ret != TRACE_SUCCESS) {
320 44 : LOGW("can not write memory info to file, ret=%d.", ret);
321 : }
322 :
323 237 : ret = TraceSafeWriteStatusInfo(fd, pid);
324 237 : if (ret != TRACE_SUCCESS) {
325 110 : LOGW("can not write process info to file, ret=%d.", ret);
326 : }
327 :
328 237 : ret = TraceSafeWriteLimitsInfo(fd, pid);
329 237 : if (ret != TRACE_SUCCESS) {
330 110 : LOGW("can not write limits info to file, ret=%d.", ret);
331 : }
332 :
333 237 : return TRACE_SUCCESS;
334 : }
335 :
336 : /**
337 : * @brief write "stack" info
338 : * @param [in] fd: handle of stack core file
339 : * @param [in] info: stack info
340 : * @return TraStatus
341 : */
342 303 : TraStatus TraceSafeWriteStackInfo(int32_t fd, const TraceStackInfo* info)
343 : {
344 303 : if (info == NULL) {
345 22 : return TRACE_INVALID_PARAM;
346 : }
347 :
348 : // write title [stack]
349 281 : TraStatus ret = TRACE_FAILURE;
350 281 : if (info->threadIdx == 0) {
351 281 : ret = TraceSafeWrite(fd, STACK_SECTION, strlen(STACK_SECTION));
352 281 : if (ret != TRACE_SUCCESS) {
353 22 : LOGE("write stack title failed, errno=%d", errno);
354 22 : return ret;
355 : }
356 : }
357 :
358 : // write stack info
359 259 : char buf[CORE_BUFFER_LEN] = {0};
360 259 : (void)snprintf_s(
361 259 : buf, CORE_BUFFER_LEN, CORE_BUFFER_LEN - 1U, "Thread %u (%d, %s)\n", info->threadIdx + 1U, info->threadTid,
362 259 : info->threadName);
363 259 : (void)TraceSafeWrite(fd, buf, strlen(buf));
364 :
365 259 : int32_t layer = info->layer;
366 259 : if (layer < 0) {
367 66 : (void)TraceSafeWrite(fd, info->errLog, strlen(info->errLog));
368 66 : (void)TraceSafeWrite(fd, "\n", 1);
369 66 : return TRACE_FAILURE;
370 : }
371 193 : if (layer >= MAX_STACK_LAYER) {
372 22 : LOGE("layer %d exceed the upper limit: %d", layer, MAX_STACK_LAYER);
373 22 : return TRACE_FAILURE;
374 : }
375 535 : for (int32_t i = 0; i <= layer; i++) {
376 386 : ret = TraceSafeWrite(fd, info->frame[i].info, strlen(info->frame[i].info));
377 386 : if (ret != TRACE_SUCCESS) {
378 22 : LOGE("write stack layer %d failed, ret=%d", i, ret);
379 22 : return ret;
380 : }
381 : }
382 149 : (void)TraceSafeWrite(fd, "\n", 1);
383 149 : return TRACE_SUCCESS;
384 : }
385 :
386 : /**
387 : * @brief write "process" info
388 : * @param [in] fd: handle of stack_core file
389 : * @param [in] info: process info
390 : * @return TraStatus
391 : */
392 237 : TraStatus TraceSafeWriteProcessInfo(int32_t fd, const TraceStackProcessInfo* info)
393 : {
394 237 : if (info == NULL) {
395 22 : return TRACE_INVALID_PARAM;
396 : }
397 : // write title [process]
398 215 : TraStatus ret = TraceSafeWrite(fd, PROCESS_SECTION, strlen(PROCESS_SECTION));
399 215 : if (ret != TRACE_SUCCESS) {
400 22 : LOGE("write process title failed, errno=%d", errno);
401 22 : return ret;
402 : }
403 :
404 : // write process info
405 193 : char data[CORE_BUFFER_LEN] = {0};
406 193 : int32_t err = snprintf_s(
407 : data, CORE_BUFFER_LEN, CORE_BUFFER_LEN - 1U,
408 : "crash reason:%d\ncrash pid:%d\ncrash tid:%d\ncrash stack base:0x%016lx\ncrash stack top:0x%016lx\n\n",
409 193 : info->signo, info->pid, info->tid, info->baseAddr, info->topAddr);
410 193 : if (err == -1) {
411 0 : LOGE("snprintf_s process info failed");
412 0 : return TRACE_FAILURE;
413 : }
414 193 : ret = TraceSafeWrite(fd, data, strlen(data));
415 193 : if (ret != TRACE_SUCCESS) {
416 22 : LOGE("write process info failed, info : %s", strerror(AdiagGetErrorCode()));
417 22 : return ret;
418 : }
419 171 : return TRACE_SUCCESS;
420 : }
421 :
422 22 : TraStatus TraceSaveProcessReg(uintptr_t* regs, uint32_t regSize)
423 : {
424 22 : errno_t err = memcpy_s(g_stackBuff.process.regs, sizeof(uintptr_t) * TRACE_CORE_REG_NUM, regs, regSize);
425 22 : if (err != EOK) {
426 22 : LOGE("memcpy failed, err = %d, errno = %d.", (int32_t)err, errno);
427 22 : return TRACE_FAILURE;
428 : }
429 0 : return TRACE_SUCCESS;
430 : }
431 :
432 0 : STATIC TraStatus TraceSaveProcessTask(int32_t pid)
433 : {
434 0 : char path[CORE_BUFFER_LEN] = {0};
435 0 : int32_t err = snprintf_s(path, CORE_BUFFER_LEN, CORE_BUFFER_LEN - 1U, "/proc/%d/cmdline", pid);
436 0 : if (err == -1) {
437 0 : LOGE("snprintf_s cmdline path failed");
438 0 : return TRACE_FAILURE;
439 : }
440 :
441 0 : int32_t cmdFd = open(path, O_RDONLY);
442 0 : if (cmdFd < 0) {
443 0 : LOGE("cmdline file open failed, errno=%d", errno);
444 0 : return TRACE_FAILURE;
445 : }
446 :
447 0 : if (TraceSafeReadLine(cmdFd, g_stackBuff.process.task, (uint32_t)sizeof(g_stackBuff.process.task)) <= 0) {
448 0 : LOGE("read task info failed, errno=%d", errno);
449 0 : TraceClose(&cmdFd);
450 0 : return TRACE_FAILURE;
451 : }
452 0 : TraceClose(&cmdFd);
453 0 : return TRACE_SUCCESS;
454 : }
455 :
456 : /**
457 : * @brief save process info
458 : * @param [in] info: stack info
459 : * @return TraStatus
460 : */
461 0 : TraStatus TraceSaveProcessInfo(const TraceStackProcessInfo* info)
462 : {
463 0 : g_stackBuff.process.pid = info->pid;
464 0 : g_stackBuff.process.crashTid = info->tid;
465 0 : g_stackBuff.process.signo = info->signo;
466 0 : g_stackBuff.process.crashTime = info->crashTime;
467 0 : g_stackBuff.process.baseAddr = info->baseAddr;
468 0 : g_stackBuff.process.topAddr = info->topAddr;
469 0 : return TraceSaveProcessTask(info->pid);
470 : }
471 :
472 : /**
473 : * @brief save stack info
474 : * @param [in] info: stack info
475 : * @return TraStatus
476 : */
477 132 : TraStatus TraceSaveStackInfo(const TraceStackInfo* info)
478 : {
479 132 : if (info == NULL) {
480 22 : return TRACE_INVALID_PARAM;
481 : }
482 110 : if (info->threadIdx >= MAX_THREAD_NUM) {
483 22 : return TRACE_INVALID_PARAM;
484 : }
485 :
486 88 : ScThreadInfo* thread = &g_stackBuff.thread[info->threadIdx];
487 88 : thread->tid = info->threadTid;
488 88 : thread->layer = info->layer;
489 88 : errno_t err = strncpy_s(thread->name, THREAD_NAME_LEN, info->threadName, strlen(info->threadName));
490 88 : if (err != EOK) {
491 22 : LOGE("strcpy thread name failed");
492 22 : return TRACE_FAILURE;
493 : }
494 :
495 66 : int32_t layer = info->layer;
496 66 : if (layer < 0) {
497 22 : return TRACE_FAILURE;
498 : }
499 44 : if (layer >= MAX_STACK_LAYER) {
500 22 : LOGE("layer %d exceed the upper limit: %d", layer, MAX_STACK_LAYER);
501 22 : return TRACE_FAILURE;
502 : }
503 :
504 22 : err = memcpy_s(
505 22 : thread->frames, sizeof(ScdFrames) * (size_t)MAX_STACK_LAYER, info->frame,
506 : sizeof(TraceFrameInfo) * (size_t)MAX_STACK_LAYER);
507 22 : if (err != EOK) {
508 22 : LOGE("memcpy thread frames failed");
509 22 : return TRACE_FAILURE;
510 : }
511 :
512 0 : return TRACE_SUCCESS;
513 : }
514 :
515 0 : TraStatus TraceSafeWriteBuff(int32_t fd)
516 : {
517 0 : TraStatus ret = TraceSafeWrite(fd, (const char*)&g_stackBuff, sizeof(g_stackBuff));
518 0 : (void)memset_s(&g_stackBuff, sizeof(struct StackcoreBuffer), 0, sizeof(struct StackcoreBuffer));
519 0 : if (ret != TRACE_SUCCESS) {
520 0 : LOGE("write buffer to file failed, info : %s", strerror(AdiagGetErrorCode()));
521 0 : return ret;
522 : }
523 0 : return TRACE_SUCCESS;
524 : }
525 :
526 167 : TraStatus TraceSafeMkdirPath(const TraceStackRecorderInfo* info)
527 : {
528 167 : if (info == NULL) {
529 22 : return TRACE_INVALID_PARAM;
530 : }
531 :
532 : // get dir time by crash time
533 145 : char timeString[TIMESTAMP_MAX_LENGTH] = {0};
534 145 : TraStatus ret = TimestampToFileStr(info->crashTime, timeString, TIMESTAMP_MAX_LENGTH);
535 145 : if (ret != TRACE_SUCCESS) {
536 22 : LOGE("get dir time failed, ret=%d", ret);
537 22 : return ret;
538 : }
539 :
540 123 : TraceDirInfo dirInfo = {TRACER_STACKCORE_NAME, info->pid, timeString, false};
541 123 : return TraceRecorderSafeMkdirPath(&dirInfo);
542 : }
543 :
544 286 : TraStatus TraceSafeGetDirPath(const TraceStackRecorderInfo* info, char* path, size_t len)
545 : {
546 286 : if ((info == NULL) || (path == NULL) || (len == 0)) {
547 66 : return TRACE_INVALID_PARAM;
548 : }
549 :
550 : // get dir time by crash time
551 220 : char timeString[TIMESTAMP_MAX_LENGTH] = {0};
552 220 : TraStatus ret = TimestampToFileStr(info->crashTime, timeString, TIMESTAMP_MAX_LENGTH);
553 220 : if (ret != TRACE_SUCCESS) {
554 22 : LOGE("get dir time failed, ret=%d", ret);
555 22 : return ret;
556 : }
557 :
558 198 : TraceDirInfo dirInfo = {TRACER_STACKCORE_NAME, info->pid, timeString, false};
559 198 : return TraceRecorderSafeGetDirPath(&dirInfo, path, len);
560 : }
561 :
562 286 : TraStatus TraceSafeGetFileName(const TraceStackRecorderInfo* info, char* name, size_t len)
563 : {
564 286 : if ((info == NULL) || (name == NULL) || (len == 0)) {
565 66 : return TRACE_INVALID_PARAM;
566 : }
567 220 : char timeString[TIMESTAMP_MAX_LENGTH] = {0};
568 220 : uint64_t fileTime = GetRealTime();
569 220 : TraStatus ret = TimestampToFileStr(fileTime, timeString, TIMESTAMP_MAX_LENGTH);
570 220 : if (ret != TRACE_SUCCESS) {
571 22 : LOGE("get dir time failed, ret=%d", ret);
572 22 : return ret;
573 : }
574 :
575 198 : int32_t err = snprintf_s(
576 198 : name, len, len - 1U, "%s_tracer_%d_%d_%s_%s", TRACER_STACKCORE_NAME, info->signo, info->tid,
577 : program_invocation_short_name, timeString);
578 198 : if (err == -1) {
579 22 : LOGE(
580 : "snprintf_s file name failed, info : %s, signo=%d, tid=%d, name=%s", strerror(AdiagGetErrorCode()),
581 : info->signo, info->tid, program_invocation_short_name);
582 22 : return TRACE_FAILURE;
583 : }
584 176 : return TRACE_SUCCESS;
585 : }
|