Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
19 {20 int i = 5;21 volatile int j = 6;2223 if (setjmp(env) == 0) { /* первый раз */24 i++;25 j++;26 printf("first time: i = %d, j = %dn", i, j);27 comeback));28 } else /* второй раз */29 printf("second time: i = %d, j = %dn", i, j);3031 return 0;32 }В этом примере сохранение своего значения ко второму вызову
printf()лишьВ-четвертых, как описано в разделе 12.5.2 «Обработка масок сигналов:
sigsetjmp()siglongjmp()setjmp()longjmp()sigsetjmp()siglongjmp()В-пятых, эти процедуры содержат поразительные возможности для утечек памяти! Рассмотрим программу, в которой
main()setjmp()malloc()longjmp()main()ch12-memleak.c1 /* ch12-memleak.с --- демонстрирует утечки памяти с помощью setjmp()/longjmp(). */23 #include <stdio.h>4 #include <malloc.h> /* для определения ptrdiff_t в GLIBC */5 #include <setjmp.h>6 #include <unistd.h>78 jmp_buf env;910 void f1(void), f2(void);1112 /* main --- утечка памяти с помощью setjmp() и longjmp() */1314 int main(void)15 {16 char *start_break;17 char *current_break;18 ptrdiff_t diff;1920 start_break = sbrk((ptrdiff_t)0);2122 if (setjmp(env) == 0) /* первый раз */23 printf("setjmp calledn");2425 current_break = sbrk((ptrdiff_t) 0);2627 diff = current_break - start_break;28 printf("memsize = %ldn", (long)diff);2930 f1();3132 return 0;33 }3435 /* f1 --- выделяет память, осуществляет вложенный вызов */3637 void f1(void)38 {39 char *p = malloc(1024);4041 f2();42 }4344 /* f2 --- выделяет память, выполняет longjmp */4546 void f2(void)47 {48 char *p = malloc(1024);4950 longjmp(env, 1);51 }Эта программа устанавливает бесконечный цикл, используя
setjmp()longjmp()sbrk()brk()sbrk()setjmp()longjmp()$ <b>ch12-memleak</b> /* Запуск программы */setjmp calledmemsize = 0memsize = 6372memsize = 6372memsize = 6372memsize = 10468memsize = 10468memsize = 14564memsize = 14564memsize = 18660memsize = 18660...Память утекает из программы, как через решето. Она работает до тех пор, пока не будет прервана от клавиатуры или пока не закончится память (в этом случае образуется основательный дамп ядра).
Каждая из функций
f1()f2()f2()longjmp()main()