You can, but manually inserting that kind of info every time gets old. That's why it's worth the initial trouble to set it up so that contextual information gets inserted automatically.
package MyFoo;
use strict;
use warnings;
use Inline C => Config =>
BUILD_NOISY => 1;
use Inline C => <<'EOC';
#line 9 "die_in_context.plx"
#define MY_PACKAGE "MyFoo"
#define kick_bucket(...) \
do_kick_bucket(__FILE__, __LINE__, MY_PACKAGE, __func__, __VA_ARGS
+__)
void
do_kick_bucket(const char *file, I32 line, const char *package,
const char *func, const char *pat, ...) {
va_list args;
SV *error_sv = newSVpvn("", 0);
va_start(args, pat);
sv_vcatpvf(error_sv, pat, &args);
va_end(args);
sv_catpvf(error_sv, " at function %s::%s at %s line %d\n",
package, func, file, line);
die(SvPVX(error_sv));
}
void
foo() {
kick_bucket("Bad Juju");
}
EOC
MyFoo::foo();
__END__
Outputs:
Bad Juju at function MyFoo::foo at die_in_context.plx line 30
The package in XS functions you ordinarily get for free, because it's part of the function name and thus gets picked up by the __func__ macro. For example when I insert a call to my Confess macro into KinoSearch::Store::InStream::new, the stack trace starts like this...
Error in function XS_KinoSearch__Store__InStream_new at lib/KinoSearch
+.xs:1742: Kill me now
__VA_ARGS__ and __func__ are C99, though, so if you need portability you have to probe for them at build time and set up alternatives for when they aren't available.
|