// See usage in header. cct_node_t* hpcrun_cct_insert_backtrace(cct_node_t* treenode, frame_t* path_beg, frame_t* path_end) { TMSG(FENCE, "insert backtrace into treenode %p", treenode); TMSG(FENCE, "backtrace below"); bool bt_ins = ENABLED(BT_INSERT); if (ENABLED(FENCE)) { ENABLE(BT_INSERT); } cct_node_t* path = cct_insert_raw_backtrace(treenode, path_beg, path_end); if (! bt_ins) DISABLE(BT_INSERT); // Put lush as_info class correction here // N.B. If 'frm' is a 1-to-1 bichord and 'path' is not (i.e., 'path' // is M-to-1 or 1-to-M), then update the association of 'path' to // reflect that 'path' is now a proxy for two bichord types (1-to-1 // and M-to-1 or 1-to-M) cct_addr_t* addr = hpcrun_cct_addr(path); lush_assoc_t as_frm = lush_assoc_info__get_assoc(path_beg->as_info); lush_assoc_t as_path = lush_assoc_info__get_assoc(addr->as_info); if (as_frm == LUSH_ASSOC_1_to_1 && as_path != LUSH_ASSOC_1_to_1) { // INVARIANT: path->as_info should be either M-to-1 or 1-to-M lush_assoc_info__set_assoc(hpcrun_cct_addr(path)->as_info, LUSH_ASSOC_1_to_1); } return path; }
void ShowContextMenu(HWND hwnd) { POINT pt; GetCursorPos(&pt); HMENU menu = CreatePopupMenu(); InsertMenu(menu, -1, MF_BYPOSITION, SWM_TOGGLE, (ENABLED()?l10n->menu_disable:l10n->menu_enable)); InsertMenu(menu, -1, MF_BYPOSITION, SWM_HIDE, l10n->menu_hide); if (update) { InsertMenu(menu, -1, MF_BYPOSITION|MF_SEPARATOR, 0, NULL); InsertMenu(menu, -1, MF_BYPOSITION, SWM_UPDATE, l10n->menu_update); } InsertMenu(menu, -1, MF_BYPOSITION|MF_SEPARATOR, 0, NULL); InsertMenu(menu, -1, MF_BYPOSITION, SWM_CONFIG, l10n->menu_config); InsertMenu(menu, -1, MF_BYPOSITION, SWM_ABOUT, l10n->menu_about); InsertMenu(menu, -1, MF_BYPOSITION|MF_SEPARATOR, 0, NULL); InsertMenu(menu, -1, MF_BYPOSITION, SWM_EXIT, l10n->menu_exit); //Track menu SetForegroundWindow(hwnd); TrackPopupMenu(menu, TPM_BOTTOMALIGN, pt.x, pt.y, 0, hwnd, NULL); DestroyMenu(menu); }
static void create_msg(char *buf, size_t buflen, bool add_thread_id, const char *tag, const char *fmt, va_list_box* box) { char fstr[MSG_BUF_SIZE]; fstr[0] = '\0'; if (add_thread_id) { if (hpcrun_using_threads_p()) { // tmp_id = TD_GET(core_profile_trace_data.id); char tmp[6] = {}; hpcrun_msg_ns(fstr, sizeof(fstr), "[%d, %s]: ", getpid(), safely_get_tid_str(tmp, sizeof(tmp))); } else { hpcrun_msg_ns(fstr, sizeof(fstr), "[%d, N]: ", getpid()); } } #if 0 if (ENABLED(PID)) { hpcrun_msg_ns(fstr, sizeof(fstr), "[%d]: ", getpid()); } #endif if (tag) { char* fstr_end = fstr + strlen(fstr); hpcrun_msg_ns(fstr_end, sizeof(fstr) - strlen(fstr), "%-5s: ", tag); } strncat(fstr, fmt, MSG_BUF_SIZE - strlen(fstr) - 5); strcat(fstr,"\n"); hpcrun_msg_vns(buf, buflen - 2, fstr, box); }
int UpdateTray() { wcsncpy(tray.szTip, (ENABLED()?l10n->tray_enabled:l10n->tray_disabled), sizeof(tray.szTip)/sizeof(wchar_t)); tray.hIcon = icon[ENABLED()?1:0]; //Only add or modify if not hidden or if balloon will be displayed if (!hide || tray.uFlags&NIF_INFO) { //Try until it succeeds, sleep 100 ms between each attempt while (Shell_NotifyIcon((tray_added?NIM_MODIFY:NIM_ADD),&tray) == FALSE) { Sleep(100); } //Success tray_added = 1; } return 0; }
static void update_cursor_with_troll(hpcrun_unw_cursor_t* cursor, int offset) { if (ENABLED(NO_TROLLING)){ TMSG(TROLL, "Trolling disabled"); hpcrun_unw_throw(); } unsigned int tmp_ra_offset; int ret = stack_troll(cursor->sp, &tmp_ra_offset, &deep_validate_return_addr, (void *)cursor); if (ret != TROLL_INVALID) { void **next_sp = ((void **)((unsigned long) cursor->sp + tmp_ra_offset)); void *next_pc = *next_sp; void *ra_loc = (void*) next_sp; // the current base pointer is a good assumption for the caller's BP void **next_bp = (void **) cursor->bp; next_sp += 1; if ( next_sp <= cursor->sp){ TMSG(TROLL,"Something weird happened! trolling from %p" " resulted in sp not advancing", cursor->pc_unnorm); hpcrun_unw_throw(); } ip_normalized_t next_pc_norm = ip_normalized_NULL; cursor->intvl = hpcrun_addr_to_interval(((char *)next_pc) + offset, next_pc, &next_pc_norm); if (cursor->intvl) { TMSG(TROLL,"Trolling advances cursor to pc = %p, sp = %p", next_pc, next_sp); TMSG(TROLL,"TROLL SUCCESS pc = %p", cursor->pc_unnorm); cursor->pc_unnorm = next_pc; cursor->bp = next_bp; cursor->sp = next_sp; cursor->ra_loc = ra_loc; cursor->pc_norm = next_pc_norm; cursor->flags = 1; // trolling_used return; // success! } TMSG(TROLL, "No interval found for trolled pc, dropping sample," " cursor pc = %p", cursor->pc_unnorm); // fall through for error handling } else { TMSG(TROLL, "Troll failed: dropping sample, cursor pc = %p", cursor->pc_unnorm); TMSG(TROLL,"TROLL FAILURE pc = %p", cursor->pc_unnorm); // fall through for error handling } // assert(0); hpcrun_unw_throw(); }
void ToggleState() { if (ENABLED()) { UnhookSystem(); } else { SendMessage(g_hwnd, WM_UPDATESETTINGS, 0, 0); HookSystem(); } }
static void vrecord(void *from, void *to, validation_status vstat) { hpcrun_validation_counts[vstat]++; if ( ENABLED(VALID_RECORD_ALL) || (vstat == UNW_ADDR_WRONG) ){ TMSG(UNW_VALID,"%p->%p (%s)", from, to, vstat2s(vstat)); } }
int main (int argc, char *argv[]) { GtkWidget *window; #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); #endif gtk_set_locale (); gtk_init (&argc, &argv); add_pixmap_directory ("/usr/share/icons/Tango/scalable/apps"); add_pixmap_directory ("/usr/share/icons/Tango/scalable/devices"); add_pixmap_directory ("."); bm.window = create_window (); bm.has_bm = g_file_test ("/usr/sbin/boot-mode", G_FILE_TEST_IS_EXECUTABLE); bm.mode = get_mode (); bm.ignore_edits = TRUE; gtk_image_set_pixel_size (GTK_IMAGE (WIDGET ("normal_image")), 128); gtk_image_set_pixel_size (GTK_IMAGE (WIDGET ("update_image")), 128); VISIBLE ("warning_box", !bm.has_bm); ENABLED ("normal_button", bm.has_bm); ENABLED ("update_button", bm.has_bm); TOGGLED ("normal_button", bm.mode == NORMAL_MODE); TOGGLED ("update_button", bm.mode == UPDATE_MODE); bm.ignore_edits = FALSE; gtk_dialog_run (GTK_DIALOG (bm.window)); if (bm.mode != (ISTOGGLED ("normal_button") ? NORMAL_MODE : UPDATE_MODE)) { update_boot_mode (); } return 0; }
void ToggleState() { if (ENABLED()) { UnhookKeyboard(); KillTimer(g_hwnd, CHECKTIMER); } else { SendMessage(g_hwnd, WM_UPDATESETTINGS, 0, 0); HookKeyboard(); } }
// FIXME: make this a selectable paramter, so that all manner of strategies // can be selected static int unw_step_prefer_sp(void) { if (ENABLED(PREFER_SP)){ return 1; } else { return 0; } // return cursor->flags; // trolling_used }
static fence_enum_t hpcrun_check_fence(void* ip) { fence_enum_t rv = FENCE_NONE; if (monitor_unwind_process_bottom_frame(ip)) rv = FENCE_MAIN; else if (monitor_unwind_thread_bottom_frame(ip)) rv = FENCE_THREAD; if (ENABLED(FENCE_UNW) && rv != FENCE_NONE) TMSG(FENCE_UNW, "%s", fence_enum_name(rv)); return rv; }
step_state hpcrun_unw_step(hpcrun_unw_cursor_t *cursor) { if ( ENABLED(DBG_UNW_STEP) ){ return dbg_unw_step(cursor); } hpcrun_unw_cursor_t saved = *cursor; step_state rv = hpcrun_unw_step_real(cursor); if ( ENABLED(UNW_VALID) ) { if (rv == STEP_OK) { // try to validate all calls, except the one at the base of the call stack from libmonitor. // rather than recording that as a valid call, it is preferable to ignore it. if (!monitor_in_start_func_wide(cursor->pc_unnorm)) { validation_status vstat = deep_validate_return_addr(cursor->pc_unnorm, (void *) &saved); vrecord(saved.pc_unnorm,cursor->pc_unnorm,vstat); } } } return rv; }
// Readers try to acquire a lock, but they don't wait if that fails. // Returns: 1 if acquired, else 0 if not. int hpcrun_dlopen_read_lock(void) { int acquire = 0; spinlock_lock(&dlopen_lock); if (dlopen_num_writers == 0 || ENABLED(DLOPEN_RISKY)) { atomic_add_i64(&dlopen_num_readers, 1L); acquire = 1; } spinlock_unlock(&dlopen_lock); return (acquire); }
// Writers always wait until they acquire the lock. Now allow writers // to lock against themselves, but only in the same thread. static void hpcrun_dlopen_write_lock(void) { int tid = monitor_get_thread_num(); int acquire = 0; do { spinlock_lock(&dlopen_lock); if (dlopen_num_writers == 0 || tid == dlopen_writer_tid) { dlopen_num_writers++; dlopen_writer_tid = tid; acquire = 1; } spinlock_unlock(&dlopen_lock); } while (! acquire); // Wait for any readers to finish. if (! ENABLED(DLOPEN_RISKY)) { while (dlopen_num_readers > 0) ; } }
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_TRAY) { if (lParam == WM_LBUTTONDOWN || lParam == WM_LBUTTONDBLCLK) { ToggleState(); if (lParam == WM_LBUTTONDBLCLK && !(GetAsyncKeyState(VK_SHIFT)&0x8000)) { SendMessage(hwnd, WM_OPENCONFIG, 0, 0); } } else if (lParam == WM_MBUTTONDOWN) { ShellExecute(NULL, L"open", inipath, NULL, NULL, SW_SHOWNORMAL); } else if (lParam == WM_RBUTTONDOWN) { ShowContextMenu(hwnd); } else if (lParam == NIN_BALLOONUSERCLICK) { hide = 0; SendMessage(hwnd, WM_COMMAND, SWM_UPDATE, 0); } else if (lParam == NIN_BALLOONTIMEOUT) { if (hide) { RemoveTray(); } } } else if (msg == WM_UPDATESETTINGS) { UpdateLanguage(); // Reload hooks if (ENABLED()) { UnhookSystem(); HookSystem(); } // Reload config language if (!wParam && IsWindow(g_cfgwnd)) { SendMessage(g_cfgwnd, WM_UPDATESETTINGS, 0, 0); } } else if (msg == WM_ADDTRAY) { hide = 0; UpdateTray(); } else if (msg == WM_HIDETRAY) { hide = 1; RemoveTray(); } else if (msg == WM_OPENCONFIG && (lParam || !hide)) { OpenConfig(wParam); } else if (msg == WM_CLOSECONFIG) { CloseConfig(); } else if (msg == WM_TASKBARCREATED) { tray_added = 0; UpdateTray(); } else if (msg == WM_COMMAND) { int wmId=LOWORD(wParam), wmEvent=HIWORD(wParam); if (wmId == SWM_TOGGLE) { ToggleState(); } else if (wmId == SWM_HIDE) { hide = 1; RemoveTray(); } else if (wmId == SWM_UPDATE) { if (MessageBox(NULL,l10n->update_dialog,APP_NAME,MB_ICONINFORMATION|MB_YESNO|MB_TOPMOST|MB_SETFOREGROUND) == IDYES) { OpenUrl(APP_URL); } } else if (wmId == SWM_CONFIG) { SendMessage(hwnd, WM_OPENCONFIG, 0, 0); } else if (wmId == SWM_ABOUT) { SendMessage(hwnd, WM_OPENCONFIG, 4, 0); } else if (wmId == SWM_EXIT) { DestroyWindow(hwnd); } } else if (msg == WM_QUERYENDSESSION && msghook) { showerror = 0; UnhookSystem(); } else if (msg == WM_DESTROY) { showerror = 0; UnhookSystem(); RemoveTray(); PostQuitMessage(0); } else if (msg == WM_LBUTTONDOWN || msg == WM_MBUTTONDOWN || msg == WM_RBUTTONDOWN) { // Hide cursorwnd if clicked on, this might happen if it wasn't hidden by hooks.c for some reason ShowWindow(hwnd, SW_HIDE); } return DefWindowProc(hwnd, msg, wParam, lParam); }
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (msg == WM_TRAY) { if (lParam == WM_LBUTTONDOWN || lParam == WM_LBUTTONDBLCLK) { ToggleState(); } else if (lParam == WM_MBUTTONDOWN) { if ((GetAsyncKeyState(VK_SHIFT)&0x8000)) { ShellExecute(NULL, L"open", inipath, NULL, NULL, SW_SHOWNORMAL); } else { HookMouse(); } } else if (lParam == WM_RBUTTONUP) { ShowContextMenu(hwnd); } } else if (msg == WM_UPDATESETTINGS) { wchar_t txt[10]; // TimerCheck KillTimer(g_hwnd, CHECKTIMER); GetPrivateProfileString(L"General", L"TimerCheck", L"0", txt, ARRAY_SIZE(txt), inipath); if (_wtoi(txt)) { SetTimer(g_hwnd, CHECKTIMER, CHECKINTERVAL, NULL); } } else if (msg == WM_TASKBARCREATED) { tray_added = 0; UpdateTray(); } else if (msg == WM_COMMAND) { int wmId=LOWORD(wParam), wmEvent=HIWORD(wParam); if (wmId == SWM_TOGGLE) { ToggleState(); } else if (wmId == SWM_ELEVATE) { wchar_t path[MAX_PATH]; GetModuleFileName(NULL, path, ARRAY_SIZE(path)); int ret = (INT_PTR) ShellExecute(NULL, L"runas", path, NULL, NULL, SW_SHOWNORMAL); if (ret > 32) { DestroyWindow(hwnd); } } else if (wmId == SWM_AUTOSTART_ON) { SetAutostart(1, 0); } else if (wmId == SWM_AUTOSTART_OFF) { SetAutostart(0, 0); } else if (wmId == SWM_AUTOSTART_ELEVATE_ON) { SetAutostart(1, 1); } else if (wmId == SWM_AUTOSTART_ELEVATE_OFF) { SetAutostart(1, 0); } else if (wmId == SWM_TIMERCHECK_ON) { WritePrivateProfileString(L"General", L"TimerCheck", L"1", inipath); SendMessage(g_hwnd, WM_UPDATESETTINGS, 0, 0); } else if (wmId == SWM_TIMERCHECK_OFF) { WritePrivateProfileString(L"General", L"TimerCheck", L"0", inipath); SendMessage(g_hwnd, WM_UPDATESETTINGS, 0, 0); } else if (wmId == SWM_WEBSITE) { OpenUrl(APP_URL); } else if (wmId == SWM_XKILL) { HookMouse(); } else if (wmId == SWM_EXIT) { DestroyWindow(hwnd); } } else if (msg == WM_DESTROY) { showerror = 0; UnhookKeyboard(); UnhookMouse(); RemoveTray(); PostQuitMessage(0); } else if (msg == WM_LBUTTONDOWN || msg == WM_MBUTTONDOWN || msg == WM_RBUTTONDOWN) { // Hide the window if clicked on, this might happen if it wasn't hidden by the hooks for some reason ShowWindow(hwnd, SW_HIDE); // Since we take away the skull, make sure we can't kill anything UnhookMouse(); } else if (msg == WM_TIMER) { if (wParam == CHECKTIMER && ENABLED()) { if (GetAsyncKeyState(VK_LCONTROL)&0x8000 && GetAsyncKeyState(VK_LMENU)&0x8000 && GetAsyncKeyState(VK_F4)&0x8000) { // Get hwnd of foreground window HWND hwnd = GetForegroundWindow(); if (hwnd == NULL) { return DefWindowProc(hwnd, msg, wParam, lParam); } // Kill it! Kill(hwnd); } else { // Reset when the user has released the keys killing = 0; } } } return DefWindowProc(hwnd, msg, wParam, lParam); }
unsigned int enabled_uint(void) { return ENABLED(); }
static step_state hpcrun_unw_step_real(hpcrun_unw_cursor_t* cursor) { cursor->fence = hpcrun_check_fence(cursor->pc_unnorm); //----------------------------------------------------------- // check if we have reached the end of our unwind, which is // demarcated with a fence. //----------------------------------------------------------- if (fence_stop(cursor->fence)) { TMSG(UNW,"unw_step: STEP_STOP, current pc in monitor fence pc=%p\n", cursor->pc_unnorm); return STEP_STOP; } // current frame void** bp = cursor->bp; void* sp = cursor->sp; void* pc = cursor->pc_unnorm; unwind_interval* uw = (unwind_interval *)cursor->intvl; int unw_res; if (!uw){ TMSG(UNW, "unw_step: invalid unw interval for cursor, trolling ..."); TMSG(TROLL, "Troll due to Invalid interval for pc %p", pc); update_cursor_with_troll(cursor, 0); return STEP_TROLL; } switch (uw->ra_status){ case RA_SP_RELATIVE: unw_res = unw_step_sp(cursor); break; case RA_BP_FRAME: unw_res = unw_step_bp(cursor); break; case RA_STD_FRAME: unw_res = unw_step_std(cursor); break; default: EMSG("unw_step: ILLEGAL UNWIND INTERVAL"); dump_ui((unwind_interval *)cursor->intvl, 0); assert(0); } if (unw_res == STEP_STOP_WEAK) unw_res = STEP_STOP; if (unw_res != STEP_ERROR) { return unw_res; } TMSG(TROLL,"unw_step: STEP_ERROR, pc=%p, bp=%p, sp=%p", pc, bp, sp); dump_ui_troll(uw); if (ENABLED(TROLL_WAIT)) { fprintf(stderr,"Hit troll point: attach w gdb to %d\n" "Maybe call dbg_set_flag(DBG_TROLL_WAIT,0) after attached\n", getpid()); // spin wait for developer to attach a debugger and clear the flag while(DEBUG_WAIT_BEFORE_TROLLING); } update_cursor_with_troll(cursor, 1); return STEP_TROLL; }