Информация об изменениях

Сообщение Re[7]: Исключение в другом потоке от 20.08.2025 10:40

Изменено 20.08.2025 10:44 ononim

Re[7]: Исключение в другом потоке
TB>А как хукать? Просто объявить такую функцию нельзя, линкер ругается. Че за ерунда, для new разрешили глобальное переопределение а для исключений нет.
Ну както так:
#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>
#include <time.h>
#include <stdlib.h>

#include <exception>


extern "C"
{
    __attribute__ ((visibility ("default"))) void __cxa_throw(void *a1, void *a2, void (*a3)(void*))
    {
        int frame = 0;
        typedef void (*t_orig__cxa_throw)(void *, void *, void (*)(void*));
        static t_orig__cxa_throw s_orig__cxa_throw = NULL;
        printf("__cxa_throw: &frame=%p\n", &frame);
        if (!s_orig__cxa_throw) {
            s_orig__cxa_throw = (t_orig__cxa_throw)dlsym(RTLD_NEXT, "__cxa_throw");
        }
        if (s_orig__cxa_throw) {
            s_orig__cxa_throw(a1, a2, a3);
        }
        abort();
    }
}

struct Exception
{
    Exception()
    {
        int frame = 0;
        printf("Exception: &frame=%p\n", &frame);
    }
    ~Exception()
    {
        int frame = 0;
        printf("~Exception: &frame=%p\n", &frame);
    }
};


void __attribute__ ((noinline)) Second()
{
    int frame = 0;
    printf("Second: &frame=%p\n", &frame);
    if (time(NULL)) {
        throw Exception();
    }
}

void __attribute__ ((noinline)) First()
{
    int frame = 0;
    printf("First: &frame=%p\n", &frame);
    Second();
}


int main(int argc, char **argv)
{
    try {
        int frame = 0;
        printf("Main: &frame=%p\n", &frame);
        First();
    } catch (Exception &e) {
        int frame = 0;
        printf("Catch: &frame=%p\n", &frame);
    }
    return 0;
}


Работает в линуксе, а для винды нужна будет другая магия.
Re[7]: Исключение в другом потоке
TB>А как хукать? Просто объявить такую функцию нельзя, линкер ругается. Че за ерунда, для new разрешили глобальное переопределение а для исключений нет.
Ну както так:
#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>
#include <time.h>
#include <stdlib.h>

#include <exception>


extern "C"
{
    __attribute__ ((visibility ("default"))) void __cxa_throw(void *a1, void *a2, void (*a3)(void*))
    {
        int frame = 0;
        typedef void (*t_orig__cxa_throw)(void *, void *, void (*)(void*));
        static t_orig__cxa_throw s_orig__cxa_throw = NULL;
        printf("__cxa_throw: &frame=%p\n", &frame);
        if (!s_orig__cxa_throw) {
            s_orig__cxa_throw = (t_orig__cxa_throw)dlsym(RTLD_NEXT, "__cxa_throw");
        }
        if (s_orig__cxa_throw) {
            s_orig__cxa_throw(a1, a2, a3);
        }
        abort();
    }
}

struct Exception
{
    Exception()
    {
        int frame = 0;
        printf("Exception: &frame=%p\n", &frame);
    }
    ~Exception()
    {
        int frame = 0;
        printf("~Exception: &frame=%p\n", &frame);
    }
};


void __attribute__ ((noinline)) Second()
{
    int frame = 0;
    printf("Second: &frame=%p\n", &frame);
    if (time(NULL)) {
        throw Exception();
    }
}

void __attribute__ ((noinline)) First()
{
    int frame = 0;
    printf("First: &frame=%p\n", &frame);
    Second();
}


int main(int argc, char **argv)
{
    try {
        int frame = 0;
        printf("Main: &frame=%p\n", &frame);
        First();
    } catch (Exception &e) {
        int frame = 0;
        printf("Catch: &frame=%p\n", &frame);
    }
    return 0;
}


Работает в линуксе, а для винды нужна будет другая магия.
А ну и еще важно чтобы эта __cxa_throw была в файле исполняемого процесса, если будет в библиотеке (.so) то чудо не случится.