Branch Coverage

src/xs/backtrace.cc
Criterion Covered Total %
branch 190 324 58.6


line true false branch
24 0 106 if (SvIS_FREED(it)) { value = "n/a"; } // already freed
0 0 if (SvIS_FREED(it)) { value = "n/a"; } // already freed
28 2 104 if (!sv.defined()) { value += "undef"; }
2 0 if (!sv.defined()) { value += "undef"; }
29 50 54 else if (sv.is_simple()) {
30 50 0 Simple simple(sv);
31 50 0 value = simple.as_string();
50 0 value = simple.as_string();
32 50 0 escape = !simple.is_like_number();
36 54 0 auto res = to_chars(buff, buff+32, uint64_t(it), 16);
37 54 0 if (!res.ec) {
40 54 0 string addr = string("(0x") + string(buff, static_cast(size)) + ")";
54 0 string addr = string("(0x") + string(buff, static_cast(size)) + ")";
54 0 string addr = string("(0x") + string(buff, static_cast(size)) + ")";
43 54 0 if (sv.is_io_ref()) { type = "IO"; }
0 54 if (sv.is_io_ref()) { type = "IO"; }
0 0 if (sv.is_io_ref()) { type = "IO"; }
44 54 0 else if(sv.is_sub_ref()) { type = "CODE"; }
45 9 else if(sv.is_sub_ref()) { type = "CODE"; }
45 0 else if(sv.is_sub_ref()) { type = "CODE"; }
45 9 0 else if(sv.is_array_ref()) { type = "ARRAY"; }
2 7 else if(sv.is_array_ref()) { type = "ARRAY"; }
2 0 else if(sv.is_array_ref()) { type = "ARRAY"; }
46 7 0 else if(sv.is_hash_ref()) { type = "HASH"; }
5 2 else if(sv.is_hash_ref()) { type = "HASH"; }
5 0 else if(sv.is_hash_ref()) { type = "HASH"; }
47 0 2 else if(sv.is_stash()) { type = "STASH"; }
0 0 else if(sv.is_stash()) { type = "STASH"; }
48 2 0 else if(sv.is_ref()) { type = "SCALAR"; }
2 0 else if(sv.is_ref()) { type = "SCALAR"; }
50 3 51 if(sv.is_object_ref()) {
51 3 0 addr = string("=") + type + addr;
3 0 addr = string("=") + type + addr;
3 0 addr = string("=") + type + addr;
52 3 0 Object obj(sv);
53 3 0 type = obj.stash().effective_name();
3 0 type = obj.stash().effective_name();
55 54 0 value = type + addr;
54 0 value = type + addr;
57 0 0 else { value = "*ERROR*"; }
59 98 8 value = (escape ? "'" : "") + value + (escape ? "'" : "");
98 8 value = (escape ? "'" : "") + value + (escape ? "'" : "");
106 0 value = (escape ? "'" : "") + value + (escape ? "'" : "");
106 0 value = (escape ? "'" : "") + value + (escape ? "'" : "");
106 0 value = (escape ? "'" : "") + value + (escape ? "'" : "");
66 91 48 if (CxTYPE(cx) == CXt_SUB && CxHASARGS(cx)) {
91 0 if (CxTYPE(cx) == CXt_SUB && CxHASARGS(cx)) {
69 91 0 auto args_count = av_top_index(ary);
74 106 91 for(decltype(off) i = off; i <= last; ++i) {
76 106 0 r.emplace_back(stringize_arg(it));
106 0 r.emplace_back(stringize_arg(it));
88 139 25 while (cx) {
89 139 0 auto pv_raw = CopSTASHPV(cx->blk_oldcop);
139 0 auto pv_raw = CopSTASHPV(cx->blk_oldcop);
139 0 auto pv_raw = CopSTASHPV(cx->blk_oldcop);
0 139 auto pv_raw = CopSTASHPV(cx->blk_oldcop);
0 0 auto pv_raw = CopSTASHPV(cx->blk_oldcop);
139 0 auto pv_raw = CopSTASHPV(cx->blk_oldcop);
0 139 auto pv_raw = CopSTASHPV(cx->blk_oldcop);
90 139 0 auto file = CopFILE(cx->blk_oldcop);
96 48 91 if ((CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT)) {
0 48 if ((CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT)) {
97 91 0 if (CvHASGV(dbcx->blk_sub.cv)) {
111 48 91 if (!library && pv_raw) { library = pv_raw; };
48 0 if (!library && pv_raw) { library = pv_raw; };
48 91 if (!library && pv_raw) { library = pv_raw; };
135 17 0 if (mg->mg_virtual == &backtrace_c_marker) {
137 17 0 delete payload;
145 12 1 if (include_c_trace) {
147 11 1 if (it.payload_exists(&backtrace_c_marker)) {
151 11 0 if (bt_info) {
152 11 0 c_trace += "C backtrace:\n";
153 11 0 c_trace += bt_info->to_string();
156 1 11 if (!c_trace) { result = "\n"; }
1 0 if (!c_trace) { result = "\n"; }
157 11 0 else { result = c_trace; }
160 12 1 if (it.payload_exists(&backtrace_perl_marker)) {
161 12 0 result += "Perl backtrace:\n";
163 12 0 auto bt = xs::in(payload.obj);
164 71 12 for (const auto& frame : bt->get_frames() ) {
165 71 0 result += frame->library + "::" + frame->name + " at " + frame->file + ":" + string::from_number(frame->line_no, 10) + "\n";
71 0 result += frame->library + "::" + frame->name + " at " + frame->file + ":" + string::from_number(frame->line_no, 10) + "\n";
71 0 result += frame->library + "::" + frame->name + " at " + frame->file + ":" + string::from_number(frame->line_no, 10) + "\n";
71 0 result += frame->library + "::" + frame->name + " at " + frame->file + ":" + string::from_number(frame->line_no, 10) + "\n";
71 0 result += frame->library + "::" + frame->name + " at " + frame->file + ":" + string::from_number(frame->line_no, 10) + "\n";
71 0 result += frame->library + "::" + frame->name + " at " + frame->file + ":" + string::from_number(frame->line_no, 10) + "\n";
71 0 result += frame->library + "::" + frame->name + " at " + frame->file + ":" + string::from_number(frame->line_no, 10) + "\n";
71 0 result += frame->library + "::" + frame->name + " at " + frame->file + ":" + string::from_number(frame->line_no, 10) + "\n";
71 0 result += frame->library + "::" + frame->name + " at " + frame->file + ":" + string::from_number(frame->line_no, 10) + "\n";
169 1 0 result += "";
174 12 0 string get_backtrace_string(Ref except) { return _get_backtrace_string(except, true); }
175 1 0 string get_backtrace_string_pp(Ref except) { return _get_backtrace_string(except, false); }
180 2 0 if (it.payload_exists(&backtrace_perl_marker)) {
181 2 0 r = new DualTrace();
2 0 r = new DualTrace();
183 2 0 auto bt = xs::in(payload.obj);
186 2 0 if (r && it.payload_exists(&backtrace_c_marker)) {
2 0 if (r && it.payload_exists(&backtrace_c_marker)) {
2 0 if (r && it.payload_exists(&backtrace_c_marker)) {
195 1 0 panda::iptr r(new DualTrace());
1 0 panda::iptr r(new DualTrace());
204 13 13 if (!ex.is_ref()) {
211 4 9 if (add_frame_info && ex.is_simple()) {
4 0 if (add_frame_info && ex.is_simple()) {
4 9 if (add_frame_info && ex.is_simple()) {
213 4 0 auto str = Simple(ex).as_string();
4 0 auto str = Simple(ex).as_string();
214 4 0 bool ends_with_newline = str.size() && str[str.size() - 1] == '\n';
4 0 bool ends_with_newline = str.size() && str[str.size() - 1] == '\n';
1 3 bool ends_with_newline = str.size() && str[str.size() - 1] == '\n';
4 0 bool ends_with_newline = str.size() && str[str.size() - 1] == '\n';
0 0 bool ends_with_newline = str.size() && str[str.size() - 1] == '\n';
215 3 1 if (!ends_with_newline) {
216 3 0 auto messed = Perl_mess_sv(aTHX_ ex, false);
217 3 0 ref = Stash("Exception::Backtrace").call("new", Simple(messed));
3 0 ref = Stash("Exception::Backtrace").call("new", Simple(messed));
3 0 ref = Stash("Exception::Backtrace").call("new", Simple(messed));
3 0 ref = Stash("Exception::Backtrace").call("new", Simple(messed));
220 10 3 if (!ref) {
221 10 0 ref = Stash("Exception::Backtrace").call("new", ex);
10 0 ref = Stash("Exception::Backtrace").call("new", ex);
10 0 ref = Stash("Exception::Backtrace").call("new", ex);
225 13 0 Ref tmp_ref(ex);
227 13 0 if (!(it.is_scalar() && it.readonly())) {
3 10 if (!(it.is_scalar() && it.readonly())) {
2 1 if (!(it.is_scalar() && it.readonly())) {
12 1 if (!(it.is_scalar() && it.readonly())) {
228 12 0 ref = tmp_ref;
237 13 6 if (!it.payload_exists(&backtrace_c_marker)) {
238 13 0 auto bt = new Backtrace();
239 13 0 it.payload_attach(bt, &backtrace_c_marker);
241 13 6 if (!it.payload_exists(&backtrace_perl_marker)) {
242 13 0 it.payload_attach(xs::out(perl_trace.get()), &backtrace_perl_marker);
13 0 it.payload_attach(xs::out(perl_trace.get()), &backtrace_perl_marker);
247 21 0 auto ref = _is_safe_to_wrap(ex, false);
248 20 1 if (ref) {
251 20 0 bool in_destroy = std::any_of(frames.begin(), frames.end(), [](auto& frame) { return frame->name == "DESTROY"; } );
252 1 19 if (in_destroy) {
255 1 0 return Simple::undef;
257 19 0 attach_backtraces(ref, perl_traces);
19 0 attach_backtraces(ref, perl_traces);
258 19 0 return Sv(ref);
260 1 0 return Simple::undef;
265 6 0 add_exception_processor([](Sv& ex) -> Sv {
266 5 0 auto ref = _is_safe_to_wrap(ex, true);
2 2 auto ref = _is_safe_to_wrap(ex, true);
267 5 0 if (ref) {
269 4 1 if (!it.payload_exists(&backtrace_c_marker)) {
271 2 0 catch (const panda::Backtrace& err) {
273 2 0 it.payload_attach(new Backtrace(err), &backtrace_c_marker);
2 0 it.payload_attach(new Backtrace(err), &backtrace_c_marker);
275 2 0 catch (...) {
277 2 0 it.payload_attach(new Backtrace(), &backtrace_c_marker);
2 0 it.payload_attach(new Backtrace(), &backtrace_c_marker);
280 4 1 if (!it.payload_exists(&backtrace_perl_marker)) {
282 4 0 it.payload_attach(xs::out(bt), &backtrace_perl_marker);
4 0 it.payload_attach(xs::out(bt), &backtrace_perl_marker);
284 5 0 return Sv(ref);
286 0 0 return ex;
287 6 0 });
290 6 0 }
6 0 }