-
-
Notifications
You must be signed in to change notification settings - Fork 987
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Function Hook to CInputManager::getMouseCoordsInternal only works in debug mode. #8845
Comments
Function getting inlined maybe? Happy to provide logs, additional info |
can you install the hook on a release version, attach gdb to the running hyprland (you can do it via ssh, because it will freeze hyprland) |
yeah, one sec EDIT:
Nested release:
Nested debug:
|
possible we tripped CFI. Try building hyprland with |
I should clarify: my "non-nested release" Hyprland is installed from pacman:
Nested release hyprland is build from hyprland-git with the appropriate commit checked out:
Compiling hyprland from the repository with
The PKGBUILD for Hyprland doesn't seem to add any additional flags - I am unsure how to recreate "nested release" Hyprland behavior/assembly. EDIT: tried compiling with code from https://github.com/hyprwm/Hyprland/releases/download/v0.46.2/source-v0.46.2.tar.gz but also got "nested release" asm. Need to match dependency versions as well? EDIT: yeah, I'm unable to reproduce the "non-nested release" asm. |
I assume without the endbr64 at the beginning, the hook works? |
No - on "nested release" my hook is never called - as if the function wasn't hooked in the first place |
Can you show the disassembly of nested release (where it doesnt work) where you already loaded and applied your hook and it doesnt work? |
|
address looks very bad. Can you post a log? Also, what does |
should be same process, different process from asm above EDIT: ones from the same process:
|
I don't think it's the same...? You can see the addr is |
Let me try again... Log: Maps: Disasm:
All PID 34038 EDIT: another set where i log the fns im hooking (?) (The hook for
|
ah right shit sorry my bad, was reading wrong, xmas moment. Can you please follow the trampoline and disassemble 64 bytes of it? (You can find it in the log, in I am pretty sure the trampoline has to be bad if calling original crashes. Also, can you try not calling the original and seeing if that works? Just return some dummy 1,1 for testing. |
The original crashes only on non-nested Hyprland, meaning it could have also been
Here is the hook static Vector2D hkGetMouseCoordsInternal(void *thisptr) {
Debug::log(LOG, "[Hyprtasking] Hooked get mouse coords internal");
return {1, 1};
} and trampoline location
with disasm
... I've also just realized that the hook does get called (sometimes). Whoops. The hook gets triggered when I left click on my plugin's overlay. This is the code that executes when that happens: static void onMouseButton(void *thisptr, SCallbackInfo &info, std::any args) {
const PHLMONITOR pMonitor = g_pCompositor->getMonitorFromCursor();
const auto view = getViewForMonitor(pMonitor);
if (pMonitor == nullptr || view == nullptr || !view->isActive())
return;
info.cancelled = true;
const auto e = std::any_cast<IPointer::SButtonEvent>(args);
if (e.button != BTN_LEFT)
return;
const bool pressed = e.state == WL_POINTER_BUTTON_STATE_PRESSED;
if (pressed) {
g_pKeybindManager->changeMouseBindMode(MBIND_MOVE);
} else {
g_pKeybindManager->changeMouseBindMode(MBIND_INVALID);
}
}
However, the hook is not called whenever the mouse moves. This is odd because I have a To call void CInputManager::mouseMoveUnified(uint32_t time, bool refocus, bool mouse) {
m_bLastInputMouse = mouse;
if (!g_pCompositor->m_bReadyToProcess || g_pCompositor->m_bIsShuttingDown || g_pCompositor->m_bUnsafeState)
return;
Vector2D const mouseCoords = getMouseCoordsInternal();
auto const MOUSECOORDSFLOORED = mouseCoords.floor();
// ...
EMIT_HOOK_EVENT_CANCELLABLE("mouseMove", MOUSECOORDSFLOORED);
} ... what? This is likely a skill issue on my part - I really appreciate your help w everything happy holidays! |
It genuinely isn't - this is unfortunately the tradeoff of hooks. Assembly debugging is very non-trivial :P Anyways, I assume that it is being called in debug on mouse move.
Let's get this straight:
Debug, nested:
Correct? Now, is "release non nested" a "git, with fcf-protection=none", or "pulled from arch repos"? If it's arch repos, try release, non-nested, with fcf-protection=none. |
Yep
That is the case. "Original crashes" is a SIGSEGV in
"Release non-nested" is the hyprland arch package.
Looks like being nested/non-nested has a difference: git checked out to v0.46.2 with Will post disasm shortly |
I have a feeling it might actually be inlining, but that wouldn't explain the crashes. (only the "not called") |
Disasm before plugin load
Disasm after plugin load
Disasm of trampoline (address from logs):
This is for non-nested git release v0.46.2, moving mouse when overlay is active (calling original fn) causes crash and plugin unload. |
hahaha okay so we got why it crashes :) thanks for the disasm, will try to fix the crash (tomorrow maybe, christmas) The "not called" is likely unfixable, unless we explicitly mark the fn as no inline. I am unsure if that's a good idea though. Wait, trampo address a bit smal, can you also pass a log? Will be useful for tomorrow. (its midnight heh) |
Unfortunate :( to the workarounds I go!
Would love a short explanation if you have the time ❤️
|
You have some weird page allocations before the code sector so hyprland tries to use them as anchors for the trampolines, where it should use the code sections. Fixed that, should not crash anymore. |
I can confirm that calling the original function no longer crashes on non-nested release git. Interestingly, compiling Hyprland with (in Vector2D __attribute__((noinline)) CInputManager::getMouseCoordsInternal() {
return g_pPointerManager->position();
} and (in Vector2D __attribute__((noinline)) getMouseCoordsInternal(); still results in my function hook only executing on mouse click. Shouldn't this prevent an inline? The onMouseMove event hook is triggered and my callback is called, but my hook for For documentation: I've gotten around this by using |
attach gdb and put a breakpoint on |
Doesn't break on mouse move, but breaks on mouse click - probably inlined. Thanks for the help! |
Already reported ? *
Regression?
No
System Info and Version
tmp.txt
Description
I'm developing a plugin that wants to hook into
getMouseCoordsInternal
to change the position of the mouse when some conditions are met.On a nested debug build of Hyprland, my plugin is able to hook just fine. However, on nested release builds of Hyprland, the API reports a successful hook, but the hook is not called. On non-nested release Hyprland, any attempts to call the original function through
m_pOriginal
ofCFunctionHook
causes a segfault in the plugin, which unloads the plugin.Here is how I am hooking the functions:
The function that should execute: (No logs are printed in release builds, while they are printed in Debug builds)
What causes the segfault in non-nested release:
const Vector2D mousePos = ((tGetMouseCoordsInternal)(g_pGetMouseCoordsInternalHook->m_pOriginal))( g_pInputManager.get());
How to reproduce
getMouseCoordsInternal
(Can attempt with https://github.com/raybbian/hyprtasking)hyprtasking:toggle
)a. Also note that hook is not called
Crash reports, logs, images, videos
Nested release:
https://github.com/user-attachments/assets/0faed1ff-46de-41ee-85e3-287863feafef
Nested debug:
https://github.com/user-attachments/assets/33789962-d09d-4295-b9d5-68a7c0391bf9
Release:
https://github.com/user-attachments/assets/7fb4330b-dea3-4147-9762-57b8f822dba4
The text was updated successfully, but these errors were encountered: