Segfault при увеличении памяти mprotect ⇐ Linux
-
Anonymous
Segfault при увеличении памяти mprotect
Я работаю на компьютере с 8 ГБ памяти с Ubuntu 20.04. Я прочитал в память файл размером 4 ГБ и теперь хочу создать буфер виртуальной памяти, используя память, оставшуюся после файла размером 4 ГБ. После прочтения файла размером 4 ГБ системный монитор сообщает, что у меня доступно примерно 2,5 ГБ.
Чтобы узнать, сколько памяти я могу использовать под управлением программы, я написал программу, которая использует «less /proc/meminfo | grep MemAvailable» для определения доступной памяти. Это возвращает значение, которое очень близко соответствует тому, что сообщает системный монитор.
Я вычитаю произвольные 100 МБ, потому что не хочу использовать всю доступную память. Для моего размера буфера остается чуть более 2,4 ГБ. Системный монитор сообщает, что у меня доступно больше.
Я создаю буфер виртуальной памяти с защитой 10 МБ. Я увеличиваю его до запрошенного размера с помощью mprotect:
int Grove_mmap(void * адрес, size_t new_length) { int64_t ret_val = mprotect (адрес, новая_длина, PROT_READ | PROT_WRITE); символ буф[1024]; strcpy(buf, strerror(errno)); printf("%d --> %s\n", errno, buf); если (ret_val != 0) { printf("Ошибка увеличения памяти: %s\n", strerror(errno)); } вернуть ret_val;
Но в строке «strcpy(buf, strerror(errno))» я получаю сообщение об ошибке:
Программа получила сигнал SIGSEGV, ошибка сегментации. __GI___pthread_rwlock_rdlock (rwlock=0x7ffff7fa4980 ) в pthread_rwlock_rdlock.c:24 24 pthread_rwlock_rdlock.c: такого файла или каталога нет.
Я запрашиваю ошибку:
(gdb) ошибка Программа получила сигнал SIGSEGV, ошибка сегментации. __errno_location() по адресу ../csu/errno-loc.c:25 25 ../csu/errno-loc.c: Нет такого файла или каталога. Сигнал об отлаживаемой программе поступил в функции, вызванной из GDB. GDB остается в кадре, в котором был получен сигнал. Чтобы изменить это поведение, используйте «set unwindonsignal on». Оценка выражения, содержащего функцию (__errno_location) будет заброшено. Когда функция завершит выполнение, GDB автоматически остановится.
Если я уменьшу запрошенную сумму до 100 МБ или 500 МБ, это будет успешно.
Я использовал эту программу много раз, но никогда с размером буфера > 500 МБ.
Итак, мой вопрос: в описанных выше обстоятельствах, как я могу определить, какой объем доступной памяти я могу использовать с помощью mprotect? Это критически важное программное обеспечение, поэтому в пользовательском пространстве не работают никакие другие программы, которые бы использовали память.
Спасибо за любую помощь.
Я работаю на компьютере с 8 ГБ памяти с Ubuntu 20.04. Я прочитал в память файл размером 4 ГБ и теперь хочу создать буфер виртуальной памяти, используя память, оставшуюся после файла размером 4 ГБ. После прочтения файла размером 4 ГБ системный монитор сообщает, что у меня доступно примерно 2,5 ГБ.
Чтобы узнать, сколько памяти я могу использовать под управлением программы, я написал программу, которая использует «less /proc/meminfo | grep MemAvailable» для определения доступной памяти. Это возвращает значение, которое очень близко соответствует тому, что сообщает системный монитор.
Я вычитаю произвольные 100 МБ, потому что не хочу использовать всю доступную память. Для моего размера буфера остается чуть более 2,4 ГБ. Системный монитор сообщает, что у меня доступно больше.
Я создаю буфер виртуальной памяти с защитой 10 МБ. Я увеличиваю его до запрошенного размера с помощью mprotect:
int Grove_mmap(void * адрес, size_t new_length) { int64_t ret_val = mprotect (адрес, новая_длина, PROT_READ | PROT_WRITE); символ буф[1024]; strcpy(buf, strerror(errno)); printf("%d --> %s\n", errno, buf); если (ret_val != 0) { printf("Ошибка увеличения памяти: %s\n", strerror(errno)); } вернуть ret_val;
Но в строке «strcpy(buf, strerror(errno))» я получаю сообщение об ошибке:
Программа получила сигнал SIGSEGV, ошибка сегментации. __GI___pthread_rwlock_rdlock (rwlock=0x7ffff7fa4980 ) в pthread_rwlock_rdlock.c:24 24 pthread_rwlock_rdlock.c: такого файла или каталога нет.
Я запрашиваю ошибку:
(gdb) ошибка Программа получила сигнал SIGSEGV, ошибка сегментации. __errno_location() по адресу ../csu/errno-loc.c:25 25 ../csu/errno-loc.c: Нет такого файла или каталога. Сигнал об отлаживаемой программе поступил в функции, вызванной из GDB. GDB остается в кадре, в котором был получен сигнал. Чтобы изменить это поведение, используйте «set unwindonsignal on». Оценка выражения, содержащего функцию (__errno_location) будет заброшено. Когда функция завершит выполнение, GDB автоматически остановится.
Если я уменьшу запрошенную сумму до 100 МБ или 500 МБ, это будет успешно.
Я использовал эту программу много раз, но никогда с размером буфера > 500 МБ.
Итак, мой вопрос: в описанных выше обстоятельствах, как я могу определить, какой объем доступной памяти я могу использовать с помощью mprotect? Это критически важное программное обеспечение, поэтому в пользовательском пространстве не работают никакие другие программы, которые бы использовали память.
Спасибо за любую помощь.
Мобильная версия