* [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