trunk/src/osd/windows/winmain.cpp
| r253575 | r253576 | |
| 58 | 58 | public: |
| 59 | 59 | // constructor which looks up the function |
| 60 | 60 | dynamic_bind(const TCHAR *dll, const char *symbol) |
| 61 | | : m_function(NULL) |
| 61 | : m_function(nullptr) |
| 62 | 62 | { |
| 63 | 63 | HMODULE module = LoadLibrary(dll); |
| 64 | | if (module != NULL) |
| 64 | if (module != nullptr) |
| 65 | 65 | m_function = reinterpret_cast<_FunctionPtr>(GetProcAddress(module, symbol)); |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | | // bool to test if the function is NULL or not |
| 69 | | operator bool() const { return (m_function != NULL); } |
| 68 | // bool to test if the function is nullptr or not |
| 69 | operator bool() const { return (m_function != nullptr); } |
| 70 | 70 | |
| 71 | 71 | // dereference to get the underlying pointer |
| 72 | 72 | _FunctionPtr operator *() const { return m_function; } |
| r253575 | r253576 | |
| 132 | 132 | bool parse_sym_line(const char *line, FPTR &address, std::string &symbol); |
| 133 | 133 | bool parse_map_line(const char *line, FPTR &address, std::string &symbol); |
| 134 | 134 | void scan_cache_for_address(FPTR address); |
| 135 | | void format_symbol(const char *name, UINT32 displacement, const char *filename = NULL, int linenumber = 0); |
| 135 | void format_symbol(const char *name, UINT32 displacement, const char *filename = nullptr, int linenumber = 0); |
| 136 | 136 | |
| 137 | 137 | static FPTR get_text_section_base(); |
| 138 | 138 | |
| 139 | 139 | struct cache_entry |
| 140 | 140 | { |
| 141 | 141 | cache_entry(FPTR address, const char *symbol) : |
| 142 | | m_next(NULL), m_address(address), m_name(symbol) { } |
| 142 | m_next(nullptr), m_address(address), m_name(symbol) { } |
| 143 | 143 | cache_entry *next() const { return m_next; } |
| 144 | 144 | |
| 145 | 145 | cache_entry * m_next; |
| r253575 | r253576 | |
| 206 | 206 | char buffer[1024]; |
| 207 | 207 | |
| 208 | 208 | // if we are in fullscreen mode, go to windowed mode |
| 209 | | if ((video_config.windowed == 0) && (win_window_list != NULL)) |
| 209 | if ((video_config.windowed == 0) && (win_window_list != nullptr)) |
| 210 | 210 | winwindow_toggle_full_screen(); |
| 211 | 211 | |
| 212 | 212 | vsnprintf(buffer, ARRAY_LENGTH(buffer), msg, args); |
| 213 | | win_message_box_utf8(win_window_list ? win_window_list->m_hwnd : NULL, buffer, emulator_info::get_appname(), MB_OK); |
| 213 | win_message_box_utf8(win_window_list ? win_window_list->m_hwnd : nullptr, buffer, emulator_info::get_appname(), MB_OK); |
| 214 | 214 | } |
| 215 | 215 | else |
| 216 | 216 | chain_output(channel, msg, args); |
| r253575 | r253576 | |
| 242 | 242 | static int timeresult = !TIMERR_NOERROR; |
| 243 | 243 | static TIMECAPS timecaps; |
| 244 | 244 | |
| 245 | | static sampling_profiler *profiler = NULL; |
| 246 | | static symbol_manager *symbols = NULL; |
| 245 | static sampling_profiler *profiler = nullptr; |
| 246 | static symbol_manager *symbols = nullptr; |
| 247 | 247 | |
| 248 | 248 | bool stack_walker::s_initialized = false; |
| 249 | 249 | |
| r253575 | r253576 | |
| 267 | 267 | const options_entry windows_options::s_option_entries[] = |
| 268 | 268 | { |
| 269 | 269 | // performance options |
| 270 | | { NULL, NULL, OPTION_HEADER, "WINDOWS PERFORMANCE OPTIONS" }, |
| 270 | { nullptr, nullptr, OPTION_HEADER, "WINDOWS PERFORMANCE OPTIONS" }, |
| 271 | 271 | { WINOPTION_PRIORITY "(-15-1)", "0", OPTION_INTEGER, "thread priority for the main game thread; range from -15 to 1" }, |
| 272 | 272 | { WINOPTION_PROFILE, "0", OPTION_INTEGER, "enables profiling, specifying the stack depth to track" }, |
| 273 | 273 | |
| 274 | 274 | // video options |
| 275 | | { NULL, NULL, OPTION_HEADER, "WINDOWS VIDEO OPTIONS" }, |
| 275 | { nullptr, nullptr, OPTION_HEADER, "WINDOWS VIDEO OPTIONS" }, |
| 276 | 276 | { WINOPTION_MENU, "0", OPTION_BOOLEAN, "enables menu bar if available by UI implementation" }, |
| 277 | 277 | |
| 278 | 278 | // DirectDraw-specific options |
| 279 | | { NULL, NULL, OPTION_HEADER, "DIRECTDRAW-SPECIFIC OPTIONS" }, |
| 279 | { nullptr, nullptr, OPTION_HEADER, "DIRECTDRAW-SPECIFIC OPTIONS" }, |
| 280 | 280 | { WINOPTION_HWSTRETCH ";hws", "1", OPTION_BOOLEAN, "enables hardware stretching" }, |
| 281 | 281 | |
| 282 | 282 | // post-processing options |
| 283 | | { NULL, NULL, OPTION_HEADER, "DIRECT3D POST-PROCESSING OPTIONS" }, |
| 284 | | { WINOPTION_HLSL_ENABLE";hlsl", "0", OPTION_BOOLEAN, "enables HLSL post-processing (PS3.0 required)" }, |
| 285 | | { WINOPTION_HLSLPATH, "hlsl", OPTION_STRING, "path to hlsl files" }, |
| 286 | | { WINOPTION_HLSL_PRESCALE_X, "0", OPTION_INTEGER, "HLSL pre-scale override factor for X (0 for auto)" }, |
| 287 | | { WINOPTION_HLSL_PRESCALE_Y, "0", OPTION_INTEGER, "HLSL pre-scale override factor for Y (0 for auto)" }, |
| 288 | | { WINOPTION_HLSL_WRITE, NULL, OPTION_STRING, "enables HLSL AVI writing (huge disk bandwidth suggested)" }, |
| 283 | { nullptr, nullptr, OPTION_HEADER, "DIRECT3D POST-PROCESSING OPTIONS" }, |
| 284 | { WINOPTION_HLSL_ENABLE";hlsl", "0", OPTION_BOOLEAN, "enables HLSL post-processing (PS3.0 required)" }, |
| 285 | { WINOPTION_HLSLPATH, "hlsl", OPTION_STRING, "path to hlsl files" }, |
| 286 | { WINOPTION_HLSL_PRESCALE_X, "0", OPTION_INTEGER, "HLSL pre-scale override factor for X (0 for auto)" }, |
| 287 | { WINOPTION_HLSL_PRESCALE_Y, "0", OPTION_INTEGER, "HLSL pre-scale override factor for Y (0 for auto)" }, |
| 288 | { WINOPTION_HLSL_WRITE, nullptr, OPTION_STRING, "enables HLSL AVI writing (huge disk bandwidth suggested)" }, |
| 289 | 289 | { WINOPTION_HLSL_SNAP_WIDTH, "2048", OPTION_STRING, "HLSL upscaled-snapshot width" }, |
| 290 | 290 | { WINOPTION_HLSL_SNAP_HEIGHT, "1536", OPTION_STRING, "HLSL upscaled-snapshot height" }, |
| 291 | 291 | { WINOPTION_SHADOW_MASK_TILE_MODE, "0", OPTION_INTEGER, "shadow mask tile mode (0 for screen based, 1 for source based)" }, |
| r253575 | r253576 | |
| 326 | 326 | { WINOPTION_FLOOR";fs_floor", "0.05,0.05,0.05", OPTION_STRING, "signal floor level" }, |
| 327 | 327 | { WINOPTION_PHOSPHOR";fs_phosphor", "0.4,0.4,0.4", OPTION_STRING, "phosphorescence decay rate (0.0 is instant, 1.0 is forever)" }, |
| 328 | 328 | /* NTSC simulation below this line */ |
| 329 | | { NULL, NULL, OPTION_HEADER, "NTSC POST-PROCESSING OPTIONS" }, |
| 329 | { nullptr, nullptr, OPTION_HEADER, "NTSC POST-PROCESSING OPTIONS" }, |
| 330 | 330 | { WINOPTION_YIQ_ENABLE";yiq", "0", OPTION_BOOLEAN, "enables YIQ-space HLSL post-processing" }, |
| 331 | 331 | { WINOPTION_YIQ_JITTER";yiqj", "0.0", OPTION_FLOAT, "Jitter for the NTSC signal processing" }, |
| 332 | 332 | { WINOPTION_YIQ_CCVALUE";yiqcc", "3.57954545", OPTION_FLOAT, "Color Carrier frequency for NTSC signal processing" }, |
| r253575 | r253576 | |
| 341 | 341 | { WINOPTION_YIQ_SCAN_TIME";yiqsc", "52.6", OPTION_FLOAT, "Horizontal scanline duration for NTSC signal processing (in usec)" }, |
| 342 | 342 | { WINOPTION_YIQ_PHASE_COUNT";yiqp", "2", OPTION_INTEGER, "Phase Count value for NTSC signal processing" }, |
| 343 | 343 | /* Vector simulation below this line */ |
| 344 | | { NULL, NULL, OPTION_HEADER, "VECTOR POST-PROCESSING OPTIONS" }, |
| 344 | { nullptr, nullptr, OPTION_HEADER, "VECTOR POST-PROCESSING OPTIONS" }, |
| 345 | 345 | { WINOPTION_VECTOR_LENGTH_SCALE";veclength", "0.5", OPTION_FLOAT, "How much length affects vector fade" }, |
| 346 | 346 | { WINOPTION_VECTOR_LENGTH_RATIO";vecsize", "500.0", OPTION_FLOAT, "Vector fade length (4.0 - vectors fade the most at and above 4 pixels, etc.)" }, |
| 347 | 347 | /* Bloom below this line */ |
| 348 | | { NULL, NULL, OPTION_HEADER, "BLOOM POST-PROCESSING OPTIONS" }, |
| 348 | { nullptr, nullptr, OPTION_HEADER, "BLOOM POST-PROCESSING OPTIONS" }, |
| 349 | 349 | { WINOPTION_BLOOM_BLEND_MODE, "0", OPTION_INTEGER, "bloom blend mode (0 for addition, 1 for darken)" }, |
| 350 | 350 | { WINOPTION_BLOOM_SCALE, "0.25", OPTION_FLOAT, "Intensity factor for bloom" }, |
| 351 | 351 | { WINOPTION_BLOOM_OVERDRIVE, "1.0,1.0,1.0", OPTION_STRING, "Overdrive factor for bloom" }, |
| r253575 | r253576 | |
| 362 | 362 | { WINOPTION_BLOOM_LEVEL10_WEIGHT, "0.01", OPTION_FLOAT, "Bloom level 10 (1x1 target) weight" }, |
| 363 | 363 | |
| 364 | 364 | // full screen options |
| 365 | | { NULL, NULL, OPTION_HEADER, "FULL SCREEN OPTIONS" }, |
| 365 | { nullptr, nullptr, OPTION_HEADER, "FULL SCREEN OPTIONS" }, |
| 366 | 366 | { WINOPTION_TRIPLEBUFFER ";tb", "0", OPTION_BOOLEAN, "enables triple buffering" }, |
| 367 | 367 | { WINOPTION_FULLSCREENBRIGHTNESS ";fsb(0.1-2.0)", "1.0", OPTION_FLOAT, "brightness value in full screen mode" }, |
| 368 | 368 | { WINOPTION_FULLSCREENCONTRAST ";fsc(0.1-2.0)", "1.0", OPTION_FLOAT, "contrast value in full screen mode" }, |
| 369 | 369 | { WINOPTION_FULLSCREENGAMMA ";fsg(0.1-3.0)", "1.0", OPTION_FLOAT, "gamma value in full screen mode" }, |
| 370 | 370 | |
| 371 | 371 | // input options |
| 372 | | { NULL, NULL, OPTION_HEADER, "INPUT DEVICE OPTIONS" }, |
| 372 | { nullptr, nullptr, OPTION_HEADER, "INPUT DEVICE OPTIONS" }, |
| 373 | 373 | { WINOPTION_GLOBAL_INPUTS ";global_inputs", "0", OPTION_BOOLEAN, "enables global inputs" }, |
| 374 | 374 | { WINOPTION_DUAL_LIGHTGUN ";dual", "0", OPTION_BOOLEAN, "enables dual lightgun input" }, |
| 375 | 375 | |
| 376 | | { NULL } |
| 376 | { nullptr } |
| 377 | 377 | }; |
| 378 | 378 | |
| 379 | 379 | //************************************************************************** |
| r253575 | r253576 | |
| 389 | 389 | { |
| 390 | 390 | // use small output buffers on non-TTYs (i.e. pipes) |
| 391 | 391 | if (!isatty(fileno(stdout))) |
| 392 | | setvbuf(stdout, (char *) NULL, _IOFBF, 64); |
| 392 | setvbuf(stdout, (char *) nullptr, _IOFBF, 64); |
| 393 | 393 | if (!isatty(fileno(stderr))) |
| 394 | | setvbuf(stderr, (char *) NULL, _IOFBF, 64); |
| 394 | setvbuf(stderr, (char *) nullptr, _IOFBF, 64); |
| 395 | 395 | |
| 396 | 396 | // initialize common controls |
| 397 | 397 | InitCommonControls(); |
| r253575 | r253576 | |
| 434 | 434 | osd_output::pop(&winerror); |
| 435 | 435 | } |
| 436 | 436 | // free symbols |
| 437 | | symbols = NULL; |
| 437 | symbols = nullptr; |
| 438 | 438 | return result; |
| 439 | 439 | } |
| 440 | 440 | |
| r253575 | r253576 | |
| 469 | 469 | |
| 470 | 470 | // if we don't have a machine yet, or if we are handling ctrl+c/ctrl+break, |
| 471 | 471 | // just terminate hard, without throwing or handling any atexit stuff |
| 472 | | if (g_current_machine == NULL || type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT) |
| 472 | if (g_current_machine == nullptr || type == CTRL_C_EVENT || type == CTRL_BREAK_EVENT) |
| 473 | 473 | { |
| 474 | 474 | fprintf(stderr, ", exiting\n"); |
| 475 | 475 | TerminateProcess(GetCurrentProcess(), MAMERR_FATALERROR); |
| r253575 | r253576 | |
| 505 | 505 | //============================================================ |
| 506 | 506 | |
| 507 | 507 | windows_osd_interface::windows_osd_interface(windows_options &options) |
| 508 | | : osd_common_t(options), m_options(options) |
| 508 | : osd_common_t(options) |
| 509 | , m_options(options) |
| 510 | , m_sliders(nullptr) |
| 509 | 511 | { |
| 510 | 512 | } |
| 511 | 513 | |
| r253575 | r253576 | |
| 525 | 527 | |
| 526 | 528 | void windows_osd_interface::video_register() |
| 527 | 529 | { |
| 528 | | video_options_add("gdi", NULL); |
| 529 | | video_options_add("d3d", NULL); |
| 530 | | video_options_add("bgfx", NULL); |
| 531 | | //video_options_add("auto", NULL); // making d3d video default one |
| 530 | video_options_add("gdi", nullptr); |
| 531 | video_options_add("d3d", nullptr); |
| 532 | video_options_add("bgfx", nullptr); |
| 533 | //video_options_add("auto", nullptr); // making d3d video default one |
| 532 | 534 | } |
| 533 | 535 | |
| 534 | 536 | //============================================================ |
| r253575 | r253576 | |
| 589 | 591 | |
| 590 | 592 | // notify listeners of screen configuration |
| 591 | 593 | std::string tempstring; |
| 592 | | for (win_window_info *info = win_window_list; info != NULL; info = info->m_next) |
| 594 | for (win_window_info *info = win_window_list; info != nullptr; info = info->m_next) |
| 593 | 595 | { |
| 594 | 596 | strprintf(tempstring, "Orientation(%s)", info->m_monitor->devicename()); |
| 595 | 597 | machine.output().set_value(tempstring.c_str(), info->m_targetorient); |
| r253575 | r253576 | |
| 609 | 611 | int watchdog = options.watchdog(); |
| 610 | 612 | if (watchdog != 0) |
| 611 | 613 | { |
| 612 | | watchdog_reset_event = CreateEvent(NULL, FALSE, FALSE, NULL); |
| 613 | | assert_always(watchdog_reset_event != NULL, "Failed to create watchdog reset event"); |
| 614 | | watchdog_exit_event = CreateEvent(NULL, TRUE, FALSE, NULL); |
| 615 | | assert_always(watchdog_exit_event != NULL, "Failed to create watchdog exit event"); |
| 616 | | watchdog_thread = CreateThread(NULL, 0, watchdog_thread_entry, (LPVOID)(FPTR)watchdog, 0, NULL); |
| 617 | | assert_always(watchdog_thread != NULL, "Failed to create watchdog thread"); |
| 614 | watchdog_reset_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); |
| 615 | assert_always(watchdog_reset_event != nullptr, "Failed to create watchdog reset event"); |
| 616 | watchdog_exit_event = CreateEvent(nullptr, TRUE, FALSE, nullptr); |
| 617 | assert_always(watchdog_exit_event != nullptr, "Failed to create watchdog exit event"); |
| 618 | watchdog_thread = CreateThread(nullptr, 0, watchdog_thread_entry, (LPVOID)(FPTR)watchdog, 0, nullptr); |
| 619 | assert_always(watchdog_thread != nullptr, "Failed to create watchdog thread"); |
| 618 | 620 | } |
| 619 | 621 | |
| 620 | 622 | // create and start the profiler |
| r253575 | r253576 | |
| 639 | 641 | void windows_osd_interface::osd_exit() |
| 640 | 642 | { |
| 641 | 643 | // no longer have a machine |
| 642 | | g_current_machine = NULL; |
| 644 | g_current_machine = nullptr; |
| 643 | 645 | |
| 644 | 646 | // cleanup sockets |
| 645 | 647 | win_cleanup_sockets(); |
| r253575 | r253576 | |
| 647 | 649 | osd_common_t::osd_exit(); |
| 648 | 650 | |
| 649 | 651 | // take down the watchdog thread if it exists |
| 650 | | if (watchdog_thread != NULL) |
| 652 | if (watchdog_thread != nullptr) |
| 651 | 653 | { |
| 652 | 654 | SetEvent(watchdog_exit_event); |
| 653 | 655 | WaitForSingleObject(watchdog_thread, INFINITE); |
| 654 | 656 | CloseHandle(watchdog_reset_event); |
| 655 | 657 | CloseHandle(watchdog_exit_event); |
| 656 | 658 | CloseHandle(watchdog_thread); |
| 657 | | watchdog_reset_event = NULL; |
| 658 | | watchdog_exit_event = NULL; |
| 659 | | watchdog_thread = NULL; |
| 659 | watchdog_reset_event = nullptr; |
| 660 | watchdog_exit_event = nullptr; |
| 661 | watchdog_thread = nullptr; |
| 660 | 662 | } |
| 661 | 663 | |
| 662 | 664 | // stop the profiler |
| 663 | | if (profiler != NULL) |
| 665 | if (profiler != nullptr) |
| 664 | 666 | { |
| 665 | 667 | profiler->stop(); |
| 666 | 668 | profiler->print_results(*symbols); |
| r253575 | r253576 | |
| 688 | 690 | |
| 689 | 691 | // walk the stack |
| 690 | 692 | while (walker.unwind()) |
| 691 | | fprintf(stderr, " %p: %p%s\n", (void *)walker.frame(), (void *)walker.ip(), (symbols == NULL) ? "" : symbols->symbol_for_address(walker.ip())); |
| 693 | fprintf(stderr, " %p: %p%s\n", (void *)walker.frame(), (void *)walker.ip(), (symbols == nullptr) ? "" : symbols->symbol_for_address(walker.ip())); |
| 692 | 694 | } |
| 693 | 695 | |
| 694 | 696 | |
| r253575 | r253576 | |
| 753 | 755 | void winmain_watchdog_ping(void) |
| 754 | 756 | { |
| 755 | 757 | // if we have a watchdog, reset it |
| 756 | | if (watchdog_reset_event != NULL) |
| 758 | if (watchdog_reset_event != nullptr) |
| 757 | 759 | SetEvent(watchdog_reset_event); |
| 758 | 760 | } |
| 759 | 761 | |
| r253575 | r253576 | |
| 866 | 868 | |
| 867 | 869 | // walk the stack |
| 868 | 870 | while (walker.unwind()) |
| 869 | | fprintf(stderr, " %p: %p%s\n", (void *)walker.frame(), (void *)walker.ip(), (symbols == NULL) ? "" : symbols->symbol_for_address(walker.ip())); |
| 871 | fprintf(stderr, " %p: %p%s\n", (void *)walker.frame(), (void *)walker.ip(), (symbols == nullptr) ? "" : symbols->symbol_for_address(walker.ip())); |
| 870 | 872 | |
| 871 | 873 | // flush stderr, so the data is actually written when output is being redirected |
| 872 | 874 | fflush(stderr); |
| r253575 | r253576 | |
| 901 | 903 | // initialize the symbols |
| 902 | 904 | if (!s_initialized && m_sym_initialize && m_stack_walk_64 && m_sym_function_table_access_64 && m_sym_get_module_base_64) |
| 903 | 905 | { |
| 904 | | (*m_sym_initialize)(m_process, NULL, TRUE); |
| 906 | (*m_sym_initialize)(m_process, nullptr, TRUE); |
| 905 | 907 | s_initialized = true; |
| 906 | 908 | } |
| 907 | 909 | } |
| r253575 | r253576 | |
| 975 | 977 | if (s_initialized) |
| 976 | 978 | { |
| 977 | 979 | #ifdef PTR64 |
| 978 | | return (*m_stack_walk_64)(IMAGE_FILE_MACHINE_AMD64, m_process, m_thread, &m_stackframe, &m_context, NULL, *m_sym_function_table_access_64, *m_sym_get_module_base_64, NULL); |
| 980 | return (*m_stack_walk_64)(IMAGE_FILE_MACHINE_AMD64, m_process, m_thread, &m_stackframe, &m_context, nullptr, *m_sym_function_table_access_64, *m_sym_get_module_base_64, nullptr); |
| 979 | 981 | #else |
| 980 | | return (*m_stack_walk_64)(IMAGE_FILE_MACHINE_I386, m_process, m_thread, &m_stackframe, &m_context, NULL, *m_sym_function_table_access_64, *m_sym_get_module_base_64, NULL); |
| 982 | return (*m_stack_walk_64)(IMAGE_FILE_MACHINE_I386, m_process, m_thread, &m_stackframe, &m_context, nullptr, *m_sym_function_table_access_64, *m_sym_get_module_base_64, nullptr); |
| 981 | 983 | #endif |
| 982 | 984 | } |
| 983 | 985 | |
| r253575 | r253576 | |
| 1056 | 1058 | if (!query_system_for_address(address)) |
| 1057 | 1059 | { |
| 1058 | 1060 | // if that fails, scan the cache if we have one |
| 1059 | | if (m_cache.first() != NULL) |
| 1061 | if (m_cache.first() != nullptr) |
| 1060 | 1062 | scan_cache_for_address(address); |
| 1061 | 1063 | |
| 1062 | 1064 | // or else try to open a sym/map file and find it there |
| r253575 | r253576 | |
| 1113 | 1115 | void symbol_manager::scan_file_for_address(FPTR address, bool create_cache) |
| 1114 | 1116 | { |
| 1115 | 1117 | bool is_symfile = false; |
| 1116 | | FILE *srcfile = NULL; |
| 1118 | FILE *srcfile = nullptr; |
| 1117 | 1119 | |
| 1118 | 1120 | #ifdef __GNUC__ |
| 1119 | 1121 | // see if we have a symbol file (gcc only) |
| 1120 | 1122 | srcfile = fopen(m_symfile.c_str(), "r"); |
| 1121 | | is_symfile = (srcfile != NULL); |
| 1123 | is_symfile = (srcfile != nullptr); |
| 1122 | 1124 | #endif |
| 1123 | 1125 | |
| 1124 | 1126 | // if not, see if we have a map file |
| 1125 | | if (srcfile == NULL) |
| 1127 | if (srcfile == nullptr) |
| 1126 | 1128 | srcfile = fopen(m_mapfile.c_str(), "r"); |
| 1127 | 1129 | |
| 1128 | 1130 | // if not, fail |
| 1129 | | if (srcfile == NULL) |
| 1131 | if (srcfile == nullptr) |
| 1130 | 1132 | return; |
| 1131 | 1133 | |
| 1132 | 1134 | // reset the best info |
| r253575 | r253576 | |
| 1179 | 1181 | FPTR best_addr = 0; |
| 1180 | 1182 | |
| 1181 | 1183 | // walk the cache, looking for valid entries |
| 1182 | | for (cache_entry *entry = m_cache.first(); entry != NULL; entry = entry->next()) |
| 1184 | for (cache_entry *entry = m_cache.first(); entry != nullptr; entry = entry->next()) |
| 1183 | 1185 | |
| 1184 | 1186 | // if this is the best one so far, remember it |
| 1185 | 1187 | if (entry->m_address <= address && entry->m_address > best_addr) |
| r253575 | r253576 | |
| 1212 | 1214 | |
| 1213 | 1215 | // first look for a (ty) entry |
| 1214 | 1216 | const char *type = strstr(line, "(ty 20)"); |
| 1215 | | if (type == NULL) |
| 1217 | if (type == nullptr) |
| 1216 | 1218 | return false; |
| 1217 | 1219 | |
| 1218 | 1220 | // scan forward in the line to find the address |
| r253575 | r253576 | |
| 1299 | 1301 | strcatprintf(m_buffer, "+0x%04x", (UINT32)displacement); |
| 1300 | 1302 | |
| 1301 | 1303 | // append file/line if present |
| 1302 | | if (filename != NULL) |
| 1304 | if (filename != nullptr) |
| 1303 | 1305 | strcatprintf(m_buffer, ", %s:%d", filename, linenumber); |
| 1304 | 1306 | |
| 1305 | 1307 | // close up the string |
| r253575 | r253576 | |
| 1319 | 1321 | |
| 1320 | 1322 | // start with the image base |
| 1321 | 1323 | PVOID base = reinterpret_cast<PVOID>(GetModuleHandleUni()); |
| 1322 | | assert(base != NULL); |
| 1324 | assert(base != nullptr); |
| 1323 | 1325 | |
| 1324 | 1326 | // make sure we have the functions we need |
| 1325 | 1327 | if (image_nt_header && image_rva_to_section) |
| 1326 | 1328 | { |
| 1327 | 1329 | // get the NT header |
| 1328 | 1330 | PIMAGE_NT_HEADERS headers = (*image_nt_header)(base); |
| 1329 | | assert(headers != NULL); |
| 1331 | assert(headers != nullptr); |
| 1330 | 1332 | |
| 1331 | 1333 | // look ourself up (assuming we are in the .text section) |
| 1332 | 1334 | PIMAGE_SECTION_HEADER section = (*image_rva_to_section)(headers, base, reinterpret_cast<FPTR>(get_text_section_base) - reinterpret_cast<FPTR>(base)); |
| 1333 | | if (section != NULL) |
| 1335 | if (section != nullptr) |
| 1334 | 1336 | return reinterpret_cast<FPTR>(base) + section->VirtualAddress; |
| 1335 | 1337 | } |
| 1336 | 1338 | |
| r253575 | r253576 | |
| 1349 | 1351 | //------------------------------------------------- |
| 1350 | 1352 | |
| 1351 | 1353 | sampling_profiler::sampling_profiler(UINT32 max_seconds, UINT8 stack_depth = 0) |
| 1352 | | : m_target_thread(NULL), |
| 1353 | | m_thread(NULL), |
| 1354 | : m_target_thread(nullptr), |
| 1355 | m_thread(nullptr), |
| 1354 | 1356 | m_thread_id(0), |
| 1355 | 1357 | m_thread_exit(false), |
| 1356 | 1358 | m_stack_depth(stack_depth), |
| r253575 | r253576 | |
| 1386 | 1388 | m_thread_exit = false; |
| 1387 | 1389 | |
| 1388 | 1390 | // start the thread |
| 1389 | | m_thread = CreateThread(NULL, 0, thread_entry, (LPVOID)this, 0, &m_thread_id); |
| 1390 | | assert_always(m_thread != NULL, "Failed to create profiler thread\n"); |
| 1391 | m_thread = CreateThread(nullptr, 0, thread_entry, (LPVOID)this, 0, &m_thread_id); |
| 1392 | assert_always(m_thread != nullptr, "Failed to create profiler thread\n"); |
| 1391 | 1393 | |
| 1392 | 1394 | // max out the priority |
| 1393 | 1395 | SetThreadPriority(m_thread, THREAD_PRIORITY_TIME_CRITICAL); |
| r253575 | r253576 | |
| 1555 | 1557 | *count += 1; |
| 1556 | 1558 | } |
| 1557 | 1559 | |
| 1558 | | // fill in any missing parts with NULLs |
| 1560 | // fill in any missing parts with nulls |
| 1559 | 1561 | for (; frame <= m_stack_depth; frame++) |
| 1560 | 1562 | *m_buffer_ptr++ = 0; |
| 1561 | 1563 | |