| 262 | } |
| 263 | |
| 264 | static void handle_stacktrace( int skip_frames = 0 ) { |
| 265 | const auto appendCrashesPath = []( std::string& crashesPath ) { |
| 266 | FileSystem::dirAddSlashAtEnd( crashesPath ); |
| 267 | crashesPath += "crashes"; |
| 268 | FileSystem::dirAddSlashAtEnd( crashesPath ); |
| 269 | }; |
| 270 | |
| 271 | std::string crashesPath( Sys::getConfigPath( "ecode" ) ); |
| 272 | appendCrashesPath( crashesPath ); |
| 273 | |
| 274 | if ( !FileSystem::fileExists( crashesPath ) && !FileSystem::makeDir( crashesPath, true ) ) { |
| 275 | crashesPath = Sys::getProcessPath(); |
| 276 | appendCrashesPath( crashesPath ); |
| 277 | FileSystem::makeDir( crashesPath, true ); |
| 278 | } |
| 279 | |
| 280 | std::string dateTimeStr( Sys::getDateTimeStr() ); |
| 281 | String::replaceAll( dateTimeStr, " ", "_" ); |
| 282 | String::replaceAll( dateTimeStr, ":", "-" ); |
| 283 | std::string crashFilePath( |
| 284 | String::format( "%sstacktrace_%s.log", crashesPath, dateTimeStr ) ); |
| 285 | |
| 286 | Printer printer; |
| 287 | printer.address = true; |
| 288 | printer.object = true; |
| 289 | |
| 290 | StackTrace st; |
| 291 | st.set_machine_type( printer.resolver().machine_type() ); |
| 292 | st.set_thread_handle( thread_handle() ); |
| 293 | st.load_here( 64 + skip_frames, ctx() ); |
| 294 | st.skip_n_firsts( skip_frames ); |
| 295 | |
| 296 | // Capture stacktrace to a string in memory |
| 297 | std::ostringstream oss; |
| 298 | printer.print( st, oss ); |
| 299 | std::string stackTraceStr = oss.str(); |
| 300 | |
| 301 | // Print to console (Keeping your existing logic active) |
| 302 | print_to_console( stackTraceStr ); |
| 303 | |
| 304 | // Write string to file |
| 305 | std::ofstream outFile( crashFilePath ); |
| 306 | if ( !outFile.is_open() ) { |
| 307 | print_to_console( "Error: Failed to open " + crashFilePath + |
| 308 | " for writing stack trace\n" + stackTraceStr ); |
| 309 | } else { |
| 310 | outFile << stackTraceStr; |
| 311 | outFile.close(); |
| 312 | } |
| 313 | |
| 314 | // Display the custom Windows dialog |
| 315 | String::replaceAll( stackTraceStr, "\n", "\r\n" ); |
| 316 | display_crash_message( crashFilePath, stackTraceStr ); |
| 317 | } |
| 318 | |
| 319 | static void print_to_console( const std::string& message ) { |
| 320 | if ( AttachConsole( ATTACH_PARENT_PROCESS ) ) { |