• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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