@@ -2003,6 +2003,206 @@ Perl_croak_popstack(void)
2003
2003
my_exit (1 );
2004
2004
}
2005
2005
2006
+ /*
2007
+ =for apidoc c_bp
2008
+
2009
+ Internal helper for C<C_BP>. Not to be called directly.
2010
+
2011
+ Prints file name, C function name, line number, and CPU the instruction
2012
+ pointer. Instruction pointer intended to be copied to a C debugger tool or
2013
+ disassembler or used with core dumps. It is a faux-function pointer to
2014
+ somewhere in the middle of the caller's C function, this address can never
2015
+ be casted from I<void *> to a function pointer, then called, a SEGV will
2016
+ occur.
2017
+
2018
+ =cut
2019
+ */
2020
+
2021
+ void
2022
+ Perl_c_bp (const char * file_metadata )
2023
+ {
2024
+ /* file_metadata is a string in the format of "XS_my_func*XSModule.c*6789"
2025
+ The 3 arguments are catted together by CPP, so in the caller,
2026
+ when using a C debugger, you press "Step One" key 2 times less, when
2027
+ using step by disassembly view. C_BP macro should never appear in
2028
+ public Stable/Gold releases of Perl core or any CPAN module. Using
2029
+ C_BP even in a alpha release, is questionable. Smokers/CI greatly
2030
+ dislike SEGVs which someone require human intervention to unfreeze
2031
+ the console or unattended CI tool.
2032
+ */
2033
+
2034
+ #ifdef WIN32
2035
+ void * ip = _ReturnAddress ();
2036
+ #elif defined(__has_builtin ) && __has_builtin (__builtin_return_address )
2037
+ void * ip = __builtin_return_address (0 );
2038
+ #else
2039
+ # if PTRSIZE == 4
2040
+ void * ip = (void * )0x12345678 ;
2041
+ # else
2042
+ void * ip = (void * )0x123456789ABCDEF0 ;
2043
+ # endif
2044
+ #endif
2045
+ //char buf [sizeof("panic: C breakpoint hit file \"%s\", function \"%s\" line %s CPU IP 0x%p\n")
2046
+ // + (U8_MAX*3) + (PTRSIZE*2) + 1];
2047
+ char buf [sizeof ("panic: C breakpoint hit file \"%.*s\", function \"%.*s\" line %.*s CPU IP 0x%p\n" )
2048
+ + (U8_MAX * 3 ) + (PTRSIZE * 2 ) + 1 ];
2049
+ int out_len ;
2050
+ U32 f_len ;
2051
+ const char * file_metadata_end ;
2052
+ const char * p ;
2053
+ char * pbuf ;
2054
+ char * pbuf2 ;
2055
+ U8 l ;
2056
+
2057
+ const char * fnc_st ;
2058
+ const char * fnc_end ;
2059
+ U8 fnc_len ;
2060
+
2061
+ const char * fn_st ;
2062
+ const char * fn_end ;
2063
+ U8 fn_len ;
2064
+
2065
+ const char * ln_st ;
2066
+ const char * ln_end ;
2067
+ U8 ln_len ;
2068
+
2069
+ PERL_ARGS_ASSERT_C_BP ;
2070
+
2071
+
2072
+ f_len = (U32 )strlen (file_metadata );
2073
+ file_metadata_end = file_metadata + f_len ;
2074
+ p = file_metadata ;
2075
+
2076
+ fnc_st = p ;
2077
+ fnc_end = memchr (fnc_st , '*' , fnc_st - file_metadata_end );
2078
+ if (!fnc_end ) {
2079
+ fnc_st = "unknown" ;
2080
+ fnc_end = fnc_st + STRLENs ("unknown" );
2081
+ p = file_metadata_end ;
2082
+ }
2083
+ else {
2084
+ p = fnc_end + 1 ;
2085
+ }
2086
+ fnc_len = (U8 )(fnc_end - fnc_st );
2087
+
2088
+ fn_st = p ;
2089
+ fn_end = memchr (fn_st , '*' , file_metadata_end - fn_st );
2090
+ if (!fn_end ) {
2091
+ fn_st = "unknown" ;
2092
+ fn_end = fn_st + STRLENs ("unknown" );
2093
+ p = file_metadata_end ;
2094
+ }
2095
+ else {
2096
+ p = fn_end + 1 ;
2097
+ }
2098
+ fn_len = (U8 )(fn_end - fn_st );
2099
+
2100
+ ln_st = p ;
2101
+ ln_end = file_metadata_end ;
2102
+ ln_len = (U8 )(ln_end - p );
2103
+ if (!ln_len ) {
2104
+ ln_st = "unknown" ;
2105
+ ln_len = STRLENs ("unknown" );
2106
+ }
2107
+ out_len = my_snprintf ((char * )buf , sizeof (buf )- 2 ,
2108
+ "panic: C breakpoint hit file \"%.*s\", function \"%.*s\" line %.*s CPU IP 0x%p" ,
2109
+ (Size_t )fn_len , fn_st , (Size_t )fnc_len , fnc_st , (Size_t )ln_len , ln_st , ip );
2110
+ buf [out_len ] = '\0' ;
2111
+
2112
+ STMT_START {
2113
+ dTHX ;
2114
+ Perl_warn (aTHX_ "%s" , (char * )buf ); /* stderr+stdout, force user to see it */
2115
+ PerlIO_flush (PerlIO_stderr ());
2116
+ PerlIO * out = PerlIO_stdout ();
2117
+ buf [out_len ] = '\n' ;
2118
+ out_len ++ ;
2119
+ buf [out_len ] = '\0' ;
2120
+ PerlIO_write (out , (char * )buf , out_len );
2121
+ PerlIO_flush (out );
2122
+ } STMT_END ;
2123
+
2124
+ return ;
2125
+ f_len = (U32 )strlen (file_metadata );
2126
+ file_metadata_end = file_metadata + f_len ;
2127
+ p = file_metadata ;
2128
+
2129
+ fnc_st = p ;
2130
+ fnc_end = memchr (fnc_st , '*' , fnc_st - file_metadata_end );
2131
+ if (!fnc_end ) {
2132
+ fnc_st = "unknown" ;
2133
+ fnc_end = fnc_st + STRLENs ("unknown" );
2134
+ p = file_metadata_end ;
2135
+ }
2136
+ else {
2137
+ fnc_end = fnc_end - 1 ;
2138
+ p = fnc_end + 1 ;
2139
+ }
2140
+ fnc_len = (U8 )(fnc_end - fnc_st );
2141
+
2142
+ fn_st = p ;
2143
+ fn_end = memchr (fn_st , '*' , file_metadata_end - fn_st );
2144
+ if (!fn_end ) {
2145
+ fn_st = "unknown" ;
2146
+ fn_end = fn_st + STRLENs ("unknown" );
2147
+ p = file_metadata_end ;
2148
+ }
2149
+ else {
2150
+ fn_end = fn_end - 1 ;
2151
+ p = fn_end + 1 ;
2152
+ }
2153
+ fn_len = (U8 )(fn_end - fn_st );
2154
+
2155
+ ln_st = p ;
2156
+ ln_end = file_metadata_end ;
2157
+ ln_len = (U8 )(ln_end - p );
2158
+ if (!ln_len ) {
2159
+ ln_st = "unknown" ;
2160
+ ln_len = STRLENs ("unknown" );
2161
+ }
2162
+
2163
+ pbuf = (char * )buf ;
2164
+ l = STRLENs ("panic: C breakpoint hit file \"" );
2165
+ pbuf2 = pbuf ;
2166
+ pbuf += l ;
2167
+ Move ("panic: C breakpoint hit file \"" , pbuf2 , l , char );
2168
+
2169
+ pbuf2 = pbuf ;
2170
+ pbuf += fn_len ;
2171
+ Move (fn_st , pbuf2 , fn_len , char );
2172
+
2173
+ l = STRLENs ("\", function \"" );
2174
+ pbuf2 = pbuf ;
2175
+ pbuf += l ;
2176
+ Move ("\", function \"" , pbuf2 , l , char );
2177
+
2178
+ pbuf2 = pbuf ;
2179
+ pbuf += fnc_len ;
2180
+ Move (fnc_st , pbuf2 , fnc_len , char );
2181
+
2182
+ l = STRLENs ("\" line " );
2183
+ pbuf2 = pbuf ;
2184
+ pbuf += l ;
2185
+ Move ("\" line " , pbuf2 , l , char );
2186
+
2187
+ pbuf2 = pbuf ;
2188
+ pbuf += ln_len ;
2189
+ Move (ln_st , pbuf2 , ln_len , char );
2190
+
2191
+ pbuf += sprintf (pbuf ," CPU IP 0x%p" , ip );
2192
+ Perl_warn_nocontext ((char * )buf ); /* stderr+stdout, force user to see it */
2193
+ STMT_START {
2194
+ dTHX ;
2195
+ PerlIO_flush (PerlIO_stderr ());
2196
+ PerlIO * out = PerlIO_stdout ();
2197
+ * pbuf = '\n' ;
2198
+ pbuf ++ ;
2199
+ * pbuf = '\0' ;
2200
+ pbuf ++ ;
2201
+ PerlIO_write (out , (char * )buf , pbuf - ((char * )buf )- 1 );
2202
+ PerlIO_flush (out );
2203
+ } STMT_END ;
2204
+ }
2205
+
2006
2206
/*
2007
2207
=for apidoc warn_sv
2008
2208
0 commit comments