* [devel] armh + libjpeg + c++ exceptions
@ 2020-06-22 10:41 Vladislav Zavjalov
2020-06-22 14:39 ` Alexey Sheplyakov
0 siblings, 1 reply; 8+ messages in thread
From: Vladislav Zavjalov @ 2020-06-22 10:41 UTC (permalink / raw)
To: ALT Linux Team development discussions
>mapsoft2 я погляжу сейчас
Поглядел, оказалась довольно необычная проблема - отказ
c++ exceptions при обработке ошибок libjpeg.
https://bugzilla.redhat.com/show_bug.cgi?id=101448
В тексте этого бага есть минимальный тест, я вставил его в свой пакет,
послал в сборочницу, и на armh он не сработал.
Там же есть ссылка на баг
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=9265,
но в нем я пока не разобрался.
Добавление "-x c++" мне не помогло.
Надеюсь, что специалисты по gcc что-нибудь посоветуют.
Добавление новой архитектуры помогает узнать
много нового и интересного!
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [devel] armh + libjpeg + c++ exceptions 2020-06-22 10:41 [devel] armh + libjpeg + c++ exceptions Vladislav Zavjalov @ 2020-06-22 14:39 ` Alexey Sheplyakov 2020-06-22 15:27 ` Alexey Sheplyakov 0 siblings, 1 reply; 8+ messages in thread From: Alexey Sheplyakov @ 2020-06-22 14:39 UTC (permalink / raw) To: devel Добрый день! On 6/22/20 2:41 PM, Vladislav Zavjalov wrote: > Там же есть ссылка на баг > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=9265, > но в нем я пока не разобрался. > > Добавление "-x c++" мне не помогло. > Надеюсь, что специалисты по gcc что-нибудь посоветуют. Тут, возможно, не специалисты по gcc, а специалисты по glibc и/или binutils потребуются. Я таковым не являюсь, но все равно немного потыкаю палочкой в этот замечательный примерчик. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [devel] armh + libjpeg + c++ exceptions 2020-06-22 14:39 ` Alexey Sheplyakov @ 2020-06-22 15:27 ` Alexey Sheplyakov 2020-06-22 15:46 ` Alexey Sheplyakov 0 siblings, 1 reply; 8+ messages in thread From: Alexey Sheplyakov @ 2020-06-22 15:27 UTC (permalink / raw) To: devel On 6/22/20 6:39 PM, Alexey Sheplyakov wrote: >> Там же есть ссылка на баг >> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=9265, >> но в нем я пока не разобрался. >> >> Добавление "-x c++" мне не помогло. >> Надеюсь, что специалисты по gcc что-нибудь посоветуют. > > Тут, возможно, не специалисты по gcc, а специалисты по glibc и/или > binutils потребуются. > > Я таковым не являюсь, но все равно немного потыкаю палочкой в этот > замечательный примерчик. Нельзя просто так взять и заставить C код бросать (C++) исключения. Как минимум нужно 1) использовать для линковки g++ (не всегда эквивалентно gcc -x c++ -lstdc++) 2) все задействованные библиотеки собирать так, чтоб в них был GNU_EH_FRAME А у нас в armh его нет: $ wget -N http://ftp.altlinux.org/pub/distributions/ALTLinux/Sisyphus/armh/RPMS.classic/libjpeg-2.0.2-alt1.armh.rpm $ mkdir -p _tmp && cd _tmp && rpm2cpio ../libjpeg-2.0.2-alt1.armh.rpm | cpio --extract --make-directories $ readelf -l usr/lib/libjpeg.so.62 Elf file type is DYN (Shared object file) Entry point 0x1a50 There are 6 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x00000000 0x00000000 0x28ca4 0x28ca4 R E 0x10000 LOAD 0x028d00 0x00038d00 0x00038d00 0x00498 0x0049c RW 0x10000 DYNAMIC 0x028f10 0x00038f10 0x00038f10 0x000f0 0x000f0 RW 0x4 NOTE 0x0000f4 0x000000f4 0x000000f4 0x00024 0x00024 R 0x4 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10 GNU_RELRO 0x028d00 0x00038d00 0x00038d00 0x00300 0x00300 R 0x1 Section to Segment mapping: Segment Sections... 00 .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame 01 .init_array .fini_array .data.rel.ro .dynamic .got .bss 02 .dynamic 03 .note.gnu.build-id 04 05 .init_array .fini_array .data.rel.ro .dynamic Выясняю, куда и почему он делся. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [devel] armh + libjpeg + c++ exceptions 2020-06-22 15:27 ` Alexey Sheplyakov @ 2020-06-22 15:46 ` Alexey Sheplyakov 2020-06-22 22:01 ` Alexey Sheplyakov 0 siblings, 1 reply; 8+ messages in thread From: Alexey Sheplyakov @ 2020-06-22 15:46 UTC (permalink / raw) To: devel On 6/22/20 7:27 PM, Alexey Sheplyakov wrote: > Нельзя просто так взять и заставить C код бросать (C++) исключения. > Как минимум нужно > > 1) использовать для линковки g++ (не всегда > эквивалентно gcc -x c++ -lstdc++) > 2) все задействованные библиотеки собирать так, чтоб в них был GNU_EH_FRAME > > А у нас в armh его нет: И не только у нас нет. Возможно, это ABI такой. Продолжаю курить документацию. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [devel] armh + libjpeg + c++ exceptions 2020-06-22 15:46 ` Alexey Sheplyakov @ 2020-06-22 22:01 ` Alexey Sheplyakov 2020-06-23 9:49 ` Vladislav Zavjalov 0 siblings, 1 reply; 8+ messages in thread From: Alexey Sheplyakov @ 2020-06-22 22:01 UTC (permalink / raw) To: devel On 6/22/20 7:46 PM, Alexey Sheplyakov wrote: > On 6/22/20 7:27 PM, Alexey Sheplyakov wrote: > >> Нельзя просто так взять и заставить C код бросать (C++) исключения. >> Как минимум нужно >> >> 1) использовать для линковки g++ (не всегда >> эквивалентно gcc -x c++ -lstdc++) >> 2) все задействованные библиотеки собирать так, чтоб в них был >> GNU_EH_FRAME >> >> А у нас в armh его нет: > > И не только у нас нет. Возможно, это ABI такой. Продолжаю курить > документацию. arm использует другой механизм разматывания стека при обработке исключений. Для того, чтобы его задействовать (в C приложениях и библиотеках), нужно собирать с опцией -funwind-tables, (и само приложение, и все библиотеки, которые могут оказаться в callchain исключения). Проверить, собрана ли библиотека/приложение нужным образом, можно командой readelf -l path/to/libthat.so | grep EXIDX Если молчит -- значит, библиотека исключения не поддерживает. $ readelf -l usr/lib/libjpeg.so.62 Elf file type is DYN (Shared object file) Entry point 0x1a50 There are 6 program headers, starting at offset 52 Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align LOAD 0x000000 0x00000000 0x00000000 0x28ca4 0x28ca4 R E 0x10000 LOAD 0x028d00 0x00038d00 0x00038d00 0x00498 0x0049c RW 0x10000 DYNAMIC 0x028f10 0x00038f10 0x00038f10 0x000f0 0x000f0 RW 0x4 NOTE 0x0000f4 0x000000f4 0x000000f4 0x00024 0x00024 R 0x4 GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10 GNU_RELRO 0x028d00 0x00038d00 0x00038d00 0x00300 0x00300 R 0x1 Section to Segment mapping: Segment Sections... 00 .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame 01 .init_array .fini_array .data.rel.ro .dynamic .got .bss 02 .dynamic 03 .note.gnu.build-id 04 05 .init_array .fini_array .data.rel.ro .dynamic т.е. наш libjpeg исключения не поддерживает. Что и подтверждает пример из https://bugzilla.redhat.com/show_bug.cgi?id=101448 Что со всем этим делать? 1. Выяснить, каковы накладные расходы на поддержку исключений 2. Решить, приемлемы ли они 3. Если да, то собрать GCC так, чтобы -funwind-tables была по умолчанию 4. Если нет, то перестать бросать исключения их C программ, или включать -funwind-tables только там, где без исключений никак не обойтись. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [devel] armh + libjpeg + c++ exceptions 2020-06-22 22:01 ` Alexey Sheplyakov @ 2020-06-23 9:49 ` Vladislav Zavjalov 2020-06-23 15:29 ` Alexey Sheplyakov 0 siblings, 1 reply; 8+ messages in thread From: Vladislav Zavjalov @ 2020-06-23 9:49 UTC (permalink / raw) To: ALT Linux Team development discussions On Tue, Jun 23, 2020 at 02:01:14AM +0400, Alexey Sheplyakov wrote: > т.е. наш libjpeg исключения не поддерживает. Что и подтверждает > пример из https://bugzilla.redhat.com/show_bug.cgi?id=101448 > > Что со всем этим делать? > > 1. Выяснить, каковы накладные расходы на поддержку исключений > 2. Решить, приемлемы ли они > 3. Если да, то собрать GCC так, чтобы -funwind-tables была по умолчанию > 4. Если нет, то перестать бросать исключения их C программ, > или включать -funwind-tables только там, где без исключений никак не > обойтись. Спасибо за подробное объяснение! В библиотеках C иногда используются callback'и, и туда легко могут попасть исключения, если их использовать с C++. И такую проблему может быть тяжело заметить. Наверное, если не собирать вообще всё с -funwind-tables, то было бы правильно уметь отлавливать такие ситуации. Например, сделать какую-то добавку в rpm set provides/requires, чтобы приложения, собранные с этим самым EXIDX зависели от библиотек с EXIDX. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [devel] armh + libjpeg + c++ exceptions 2020-06-23 9:49 ` Vladislav Zavjalov @ 2020-06-23 15:29 ` Alexey Sheplyakov 2020-06-23 16:49 ` Vladislav Zavjalov 0 siblings, 1 reply; 8+ messages in thread From: Alexey Sheplyakov @ 2020-06-23 15:29 UTC (permalink / raw) To: devel Добрый вечер! On 6/23/20 1:49 PM, Vladislav Zavjalov wrote: > В библиотеках C иногда используются callback'и, > и туда легко могут попасть исключения, если их использовать с C++. Могут. Например, вот так: $ cat exc-leak.c #include <string.h> #include <stdlib.h> #include <stdio.h> extern "C" void f(char const* str) { if (str[0] != 'x') throw 42; } extern "C" int doit(void (*f)(char const*)) { char *str = strdup("abc"); if (!str) return 1; f(str); free(str); return 0; } int main(int argc, char **argv) { try { doit(f); return 0; } catch (int x) { fprintf(stderr, "caught int: %d\n", x); return 1; } return 2; } $ g++ -g -Wall -x c++ exc-leak.c $ ./a.out caught int: 42 $ uname -m x86_64 Вроде бы работает. За исключением того, что free() не вызывается. А если б там был pthread_mutex_lock? $ valgrind --leak-check=yes -v ./a.out ==9334== ==9334== HEAP SUMMARY: ==9334== in use at exit: 4 bytes in 1 blocks ==9334== total heap usage: 3 allocs, 2 frees, 72,840 bytes allocated ==9334== ==9334== Searching for pointers to 1 not-freed blocks ==9334== Checked 111,592 bytes ==9334== ==9334== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==9334== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==9334== by 0x547A9B9: strdup (strdup.c:42) ==9334== by 0x108A0F: doit (exc-leak.c:11) ==9334== by 0x108A5D: main (exc-leak.c:21) ==9334== ==9334== LEAK SUMMARY: ==9334== definitely lost: 4 bytes in 1 blocks ==9334== indirectly lost: 0 bytes in 0 blocks ==9334== possibly lost: 0 bytes in 0 blocks ==9334== still reachable: 0 bytes in 0 blocks ==9334== suppressed: 0 bytes in 0 blocks ==9334== ==9334== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) ==9334== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) asheplyakov@alexnuc:~/work/armhf$ Бросаться из C кода C++ исключениями -- почти всегда плохо. Единственное, для чего бы я так делал -- аварийное завершение программы. Так что те ABI/архитектуры, которые это лихачество НЕ позволяют, делают проблему явной и облегчают жизнь программиста. > И такую проблему может быть тяжело заметить. 1) valgrind (даже на x86) отлавливает многие такие лихачества (потому что они зачастую приводят к утечке памяти) 2) arm одноплатников ценой < 2000 р полно, легко собрать и запустить. Cойдет и rpi[234] (с 32-bit gnueabi userspace) 3) qemu-user позволяет не тратиться на одноплатники. > Наверное, если не собирать вообще всё с -funwind-tables, > то было бы правильно уметь отлавливать такие ситуации. > Например, сделать какую-то добавку в rpm set provides/requires, > чтобы приложения, собранные с этим самым EXIDX зависели от библиотек > с EXIDX. Убежден, что кривой код нужно чинить, а не изобретать средства, позволяющие ему и дальше быть кривым. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [devel] armh + libjpeg + c++ exceptions 2020-06-23 15:29 ` Alexey Sheplyakov @ 2020-06-23 16:49 ` Vladislav Zavjalov 0 siblings, 0 replies; 8+ messages in thread From: Vladislav Zavjalov @ 2020-06-23 16:49 UTC (permalink / raw) To: ALT Linux Team development discussions On Tue, Jun 23, 2020 at 07:29:25PM +0400, Alexey Sheplyakov wrote: > Вроде бы работает. За исключением того, что free() не вызывается. > А если б там был pthread_mutex_lock? ... > Бросаться из C кода C++ исключениями -- почти всегда плохо. > Единственное, для чего бы я так делал -- аварийное завершение программы. Не знал, постараюсь больше так не делать! ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2020-06-23 16:49 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-06-22 10:41 [devel] armh + libjpeg + c++ exceptions Vladislav Zavjalov 2020-06-22 14:39 ` Alexey Sheplyakov 2020-06-22 15:27 ` Alexey Sheplyakov 2020-06-22 15:46 ` Alexey Sheplyakov 2020-06-22 22:01 ` Alexey Sheplyakov 2020-06-23 9:49 ` Vladislav Zavjalov 2020-06-23 15:29 ` Alexey Sheplyakov 2020-06-23 16:49 ` Vladislav Zavjalov
ALT Linux Team development discussions This inbox may be cloned and mirrored by anyone: git clone --mirror http://lore.altlinux.org/devel/0 devel/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 devel devel/ http://lore.altlinux.org/devel \ devel@altlinux.org devel@altlinux.ru devel@lists.altlinux.org devel@lists.altlinux.ru devel@linux.iplabs.ru mandrake-russian@linuxteam.iplabs.ru sisyphus@linuxteam.iplabs.ru public-inbox-index devel Example config snippet for mirrors. Newsgroup available over NNTP: nntp://lore.altlinux.org/org.altlinux.lists.devel AGPL code for this site: git clone https://public-inbox.org/public-inbox.git