1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "dfx_assist.h"
17 #include "ace_log.h"
18 #include "jerryscript-core.h"
19 #include "presets/console_log_impl.h"
20
21 namespace OHOS {
22 namespace ACELite {
DumpErrorCode(const jerry_value_t errorValue)23 void DfxAssist::DumpErrorCode(const jerry_value_t errorValue)
24 {
25 const uint16_t errorMsgMaxLength = 128;
26 if (!jerry_is_feature_enabled(JERRY_FEATURE_ERROR_MESSAGES)) {
27 return;
28 }
29
30 jerry_value_t errValue = jerry_get_value_from_error(errorValue, false);
31 jerry_value_t errStrVal = jerry_value_to_string(errValue);
32 jerry_release_value(errValue);
33
34 if (jerry_value_is_error(errStrVal)) {
35 /* Avoid recursive error throws. */
36 HILOG_ERROR(HILOG_MODULE_ACE, "[Error value to string failed]");
37 jerry_release_value(errStrVal);
38 return;
39 }
40
41 jerry_size_t errStrSize = jerry_get_utf8_string_size(errStrVal);
42 if (errStrSize >= errorMsgMaxLength) {
43 HILOG_ERROR(HILOG_MODULE_ACE, "[Error message too long]");
44 jerry_release_value(errStrVal);
45 return;
46 }
47
48 jerry_char_t *errStrBuffer = static_cast<jerry_char_t *>(ace_malloc(sizeof(jerry_char_t) * (errStrSize + 1)));
49 if (errStrBuffer == nullptr) {
50 HILOG_ERROR(HILOG_MODULE_ACE, "malloc memory failed!");
51 jerry_release_value(errStrVal);
52 return;
53 }
54 jerry_size_t stringEnd = jerry_string_to_utf8_char_buffer(errStrVal, errStrBuffer, errStrSize);
55 errStrBuffer[stringEnd] = '\0';
56 // output to platform trace
57 HILOG_ERROR(HILOG_MODULE_ACE, " [JS Error]: %{public}s", reinterpret_cast<char *>(errStrBuffer));
58 // output to user console
59 LogString(LogLevel::LOG_LEVEL_ERR, "[JS Exception]: ");
60 LogString(LogLevel::LOG_LEVEL_ERR, reinterpret_cast<char *>(errStrBuffer));
61 // output line separator to trigger trace output
62 LogString(LogLevel::LOG_LEVEL_ERR, "\n");
63 ace_free(errStrBuffer);
64 errStrBuffer = nullptr;
65 jerry_release_value(errStrVal);
66 }
67
DumpErrorMessage(const jerry_value_t errorValue)68 void DfxAssist::DumpErrorMessage(const jerry_value_t errorValue)
69 {
70 const uint16_t stackMsgMaxLength = 256;
71 const uint8_t arrMaxLength = 32;
72 jerry_value_t stackStr = jerry_create_string(reinterpret_cast<const jerry_char_t *>("stack"));
73 jerry_value_t errorVal = jerry_get_value_from_error(errorValue, false);
74
75 jerry_value_t backtraceVal = jerry_get_property(errorVal, stackStr);
76 jerry_release_value(stackStr);
77 jerry_release_value(errorVal);
78
79 if (jerry_value_is_error(backtraceVal) || !(jerry_value_is_array(backtraceVal))) {
80 jerry_release_value(backtraceVal);
81 return;
82 }
83
84 uint32_t length = jerry_get_array_length(backtraceVal);
85 if (length == 0) {
86 jerry_release_value(backtraceVal);
87 return;
88 }
89 if (length > arrMaxLength) {
90 length = arrMaxLength;
91 }
92
93 jerry_char_t *errStrBuffer = static_cast<jerry_char_t *>(ace_malloc(sizeof(jerry_char_t) * (stackMsgMaxLength)));
94 if (errStrBuffer == nullptr) {
95 HILOG_ERROR(HILOG_MODULE_ACE, "malloc memory failed!");
96 jerry_release_value(backtraceVal);
97 return;
98 }
99 HILOG_ERROR(HILOG_MODULE_ACE, "[Exception backtrace]:");
100 for (uint32_t i = 0; i < length; i++) {
101 jerry_value_t itemVal = jerry_get_property_by_index(backtraceVal, i);
102 jerry_size_t strSize = 0;
103 if (!jerry_value_is_error(itemVal) && jerry_value_is_string(itemVal)) {
104 strSize = jerry_get_utf8_string_size(itemVal);
105 }
106
107 if (strSize >= stackMsgMaxLength) {
108 HILOG_ERROR(HILOG_MODULE_ACE, "%{public}hhu: [Backtrace string too long]", i);
109 } else {
110 jerry_size_t stringEnd = jerry_string_to_utf8_char_buffer(itemVal, errStrBuffer, strSize);
111 errStrBuffer[stringEnd] = '\0';
112 HILOG_ERROR(HILOG_MODULE_ACE, "%{public}u: %{public}s", i, reinterpret_cast<char *>(errStrBuffer));
113 }
114 jerry_release_value(itemVal);
115 }
116 ace_free(errStrBuffer);
117 errStrBuffer = nullptr;
118 jerry_release_value(backtraceVal);
119 }
120 } // namespace ACELite
121 } // namespace OHOS
122