| 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 | } |