#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
void run_test(int flag, const char *flag_name, int call_broken) {
printf("\n=== Тест с флагом %s ===\n", flag_name);
// Сброс старых ошибок
dlerror();
// 1. Пытаемся загрузить библиотеку
void *handle = dlopen("./libbroken.so", flag);
char *error = dlerror();
if (error != NULL) {
printf("[ОШИБКА dlerror] dlopen не удался: %s\n", error);
return; // Завершаем этот тест, так как библиотека не загрузилась
}
printf("[ОК] dlopen успешен\n");
// 2. Ищем и вызываем нормальную функцию
int (*add_fn)(int, int) = (int (*)(int, int))dlsym(handle, "add");
error = dlerror();
if (error == NULL) {
printf("[ОК] Функция add найдена, 10+5 = %d\n", add_fn(10, 5));
}
// 3. Ищем broken_function
int (*broken_fn)(int) = (int (*)(int))dlsym(handle, "broken_function");
error = dlerror();
if (error == NULL) {
printf("[ОК] broken_function найдена\n");
}
// 4. Вызываем ломающую функцию, если разрешено параметром
if (call_broken) {
printf("Пробуем вызвать broken_function...\n");
broken_fn(42);
}
dlclose(handle);
}
int main() {
// Тест 1: С флагом RTLD_NOW. Ошибка произойдет сразу в dlopen()
run_test(RTLD_NOW, "RTLD_NOW", 0);
// Тест 2: С флагом RTLD_LAZY. dlopen() пройдет, но вызов функции уронит процесс
run_test(RTLD_LAZY, "RTLD_LAZY", 1);
return 0;
}