1 /*
2 * Copyright (c) 2023 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 //! Panic trigger for Rust.
17
18 extern crate panic_handler;
19 extern crate stacktrace_rust;
20
21 use std::{panic, thread};
22 use hilog_rust::{hilog, HiLogLabel, LogType};
23 use std::ffi::{c_char, CString};
24
25 const LOG_LABEL: HiLogLabel = HiLogLabel {
26 log_type: LogType::LogCore,
27 domain: 0xd003200,
28 tag: "testTag",
29 };
30
31 /// function main
main()32 fn main() {
33 panic_handler::init();
34 let args: Vec<String> = std::env::args().collect();
35
36 if args.len() < 2 {
37 println!("Invalid arguments.");
38 usage(&args);
39 return;
40 }
41
42 test_panic(&args);
43 }
44
usage(args: &[String])45 fn usage(args: &[String]) {
46 println!("Usage:");
47 println!("{} cmd [option]", args[0]);
48 println!("cmd:");
49 println!("\tmain\t\tConstruct a panic in the main thread.");
50 println!("\t\t\tSpecifies the number of hilog lines using options.");
51 println!("\tchild\t\tConstruct a panic in the child thread.");
52 println!("\t\t\tSpecifies the number of hilog lines using options.");
53 println!("\tmulti\t\tMulti-thread test C language interface GetTrace.");
54 println!("\tprint_trace\tTest the PrintTrace interface in C language.");
55 println!("\tget_trace\tTest the GetTrace interface in C language.");
56 }
57
test_panic(args: &[String])58 fn test_panic(args: &[String]) {
59 let read_cnt = |args: &[String]| -> Option<u32> {
60 match args.len() {
61 3 => Some(args[2].parse().unwrap()),
62 4 .. => {
63 usage(args);
64 None
65 },
66 _ => Some(0),
67 }
68 };
69 match args[1].as_str() {
70 "main" => {
71 let Some(hilog_cnt) = read_cnt(args) else {
72 return;
73 };
74 for cnt in 1 ..= hilog_cnt {
75 hilog_rust::info!(LOG_LABEL, "hilog print test. No.{cnt}");
76 }
77 panic_main();
78 },
79 "child" => {
80 let Some(hilog_cnt) = read_cnt(args) else {
81 return;
82 };
83 for cnt in 1 ..= hilog_cnt {
84 hilog_rust::info!(LOG_LABEL, "hilog print test. No.{cnt}");
85 }
86 panic_child();
87 },
88 "multi" => get_trace_in_multi_thread(),
89 "print_trace" => {
90 stacktrace_rust::print_trace(1);
91 },
92 "get_trace" => {
93 let ret = stacktrace_rust::get_trace(false);
94 println!("{}", ret);
95 },
96 _ => usage(args),
97 }
98 }
99
panic_main()100 fn panic_main() {
101 panic!("panic in main thread");
102 }
103
panic_child()104 fn panic_child() {
105 let ret = thread::spawn(move || {
106 panic!("panic in child thread");
107 }).join();
108 println!("{:?}", ret);
109 }
110
get_trace_in_multi_thread()111 fn get_trace_in_multi_thread() {
112 let mut handles = vec![];
113 for _ in 0..50 {
114 let handle = thread::spawn(move || {
115 let trace = stacktrace_rust::get_trace(false);
116 println!("{}", trace);
117 });
118 handles.push(handle);
119 }
120 for handle in handles {
121 handle.join().unwrap();
122 }
123 }
124