AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / user-65600

Jon's questions

Martin Hope
Jon
Asked: 2024-12-29 05:11:19 +0800 CST

Como faço para forçar a desativação de exceções do C++?

  • 11

Estou usando C++ para um projeto de firmware de baixo nível para um microcontrolador. Tudo estava bem por um tempo, com o tamanho do código mantido muito pequeno, até que introduzi esta linha de código:

    uint8_t index = __builtin_ctz(exti_set_mask);
    auto &gpio_irq_info = irq_callback_table[index];

O problema aqui é que irq_callback_tableé um std::array<>de tamanho 16. exti_set_maskÉ um uint16_tque provavelmente está sendo promovido para uma uint32_t(arquitetura de CPU de 32 bits), então o compilador não pode ter certeza de que o resultado de __builtin_ctz()retorna algo menor que 16. Com o potencial de um acesso fora dos limites, o tamanho do código do programa explode por causa de todo o código adicionado para dar suporte ao lançamento de uma exceção.

Mascarar o resultado antes de usá-lo como índice elimina todo esse código de exceção:

uint8_t index = __builtin_ctz(exti_set_mask) & 0xf;
auto &gpio_irq_info = irq_callback_table[index];

O que reduz o tamanho do código do programa para cerca de 4 kB contra 90 kB!

Tenho essas bandeiras definidas via meson:

# Specify global compiler flags.
add_project_arguments(
    # Free standing environment (no OS, or stdlib)
    '-ffreestanding', '-nostdlib', '-specs=nosys.specs',
    # Enable linker garbage collection
    '-ffunction-sections', '-fdata-sections',
    # No dynamic memory allocation
    '-fno-builtin-malloc', '-fno-builtin-calloc',
    '-fno-builtin-realloc', '-fno-builtin-free',
    # Debug optimization
    '-Og',
    language: ['cpp', 'c']
)
add_project_arguments(
    '-std=c++20',
    '-fno-exceptions',
    '-fno-rtti',
    language: ['cpp']
)

Mas o -fno-exceptionssinalizador não parece ser suficiente para evitar a emissão de código de exceção. Idealmente, eu gostaria que qualquer emissão potencial de exceções (ou malloc, etc.) aparecesse como um aviso ou erro. Alguma ideia de como fazer isso?


EDIT: Para aqueles que desejam comparar a saída do arquivo .elf objdump, aqui está o .elf totalmente vinculado com o índice mascarado: https://pastebin.com/hSJgF3PW

E o .elf com o índice não mascarado:

  • https://pastebin.com/p9yDxdjx pt1
  • https://pastebin.com/NU5nV0tr pt2
  • https://pastebin.com/9CX1EtH0 pt3
  • https://pastebin.com/evvnmCCa pt4

A função onde os dois se desviam:

Índice não mascarado:

08000d1c <(anonymous namespace)::CommonISRHandler(unsigned short)>:
void CommonISRHandler([[maybe_unused]] uint16_t exti_set_mask) {
 8000d1c:   b570        push    {r4, r5, r6, lr}
 8000d1e:   0005        movs    r5, r0
  while (exti_set_mask) {
 8000d20:   e011        b.n 8000d46 <(anonymous namespace)::CommonISRHandler(unsigned short)+0x2a>
      // Element access.
      [[__nodiscard__]]
      _GLIBCXX17_CONSTEXPR reference
      operator[](size_type __n) noexcept
      {
    __glibcxx_requires_subscript(__n);
 8000d22:   4b18        ldr r3, [pc, #96]   @ (8000d84 <(anonymous namespace)::CommonISRHandler(unsigned short)+0x68>)
 8000d24:   4a18        ldr r2, [pc, #96]   @ (8000d88 <(anonymous namespace)::CommonISRHandler(unsigned short)+0x6c>)
 8000d26:   4819        ldr r0, [pc, #100]  @ (8000d8c <(anonymous namespace)::CommonISRHandler(unsigned short)+0x70>)
 8000d28:   21ca        movs    r1, #202    @ 0xca
 8000d2a:   f000 f97d   bl  8001028 <std::__glibcxx_assert_fail(char const*, int, char const*, char const*)>
    EXTI->RPR1 &= (1 << index);
 8000d2e:   4a18        ldr r2, [pc, #96]   @ (8000d90 <(anonymous namespace)::CommonISRHandler(unsigned short)+0x74>)
 8000d30:   68d1        ldr r1, [r2, #12]
 8000d32:   2301        movs    r3, #1
 8000d34:   40a3        lsls    r3, r4
 8000d36:   4019        ands    r1, r3
 8000d38:   60d1        str r1, [r2, #12]
    EXTI->FPR1 &= (1 << index);
 8000d3a:   6911        ldr r1, [r2, #16]
 8000d3c:   4019        ands    r1, r3
 8000d3e:   6111        str r1, [r2, #16]
    exti_set_mask &= ~(1 << index);
 8000d40:   43db        mvns    r3, r3
 8000d42:   b21b        sxth    r3, r3
 8000d44:   401d        ands    r5, r3
  while (exti_set_mask) {
 8000d46:   2d00        cmp r5, #0
 8000d48:   d01a        beq.n   8000d80 <(anonymous namespace)::CommonISRHandler(unsigned short)+0x64>
    uint8_t index = __builtin_ctz(exti_set_mask);
 8000d4a:   0028        movs    r0, r5
 8000d4c:   f7ff fa40   bl  80001d0 <__ctzsi2>
    auto &gpio_irq_info = irq_callback_table[index];
 8000d50:   24ff        movs    r4, #255    @ 0xff
 8000d52:   4004        ands    r4, r0
 8000d54:   2c0f        cmp r4, #15
 8000d56:   d8e4        bhi.n   8000d22 <(anonymous namespace)::CommonISRHandler(unsigned short)+0x6>
    return stub_ptr != nullptr;
 8000d58:   4b0e        ldr r3, [pc, #56]   @ (8000d94 <(anonymous namespace)::CommonISRHandler(unsigned short)+0x78>)
 8000d5a:   0062        lsls    r2, r4, #1
 8000d5c:   1912        adds    r2, r2, r4
 8000d5e:   0092        lsls    r2, r2, #2
 8000d60:   189b        adds    r3, r3, r2
 8000d62:   689b        ldr r3, [r3, #8]
    if (gpio_irq_info.callback.IsValid()) {
 8000d64:   2b00        cmp r3, #0
 8000d66:   d0e2        beq.n   8000d2e <(anonymous namespace)::CommonISRHandler(unsigned short)+0x12>
      gpio_irq_info.callback(gpio_irq_info.pin);
 8000d68:   4a0a        ldr r2, [pc, #40]   @ (8000d94 <(anonymous namespace)::CommonISRHandler(unsigned short)+0x78>)
 8000d6a:   0060        lsls    r0, r4, #1
 8000d6c:   1901        adds    r1, r0, r4
 8000d6e:   0089        lsls    r1, r1, #2
 8000d70:   5c89        ldrb    r1, [r1, r2]
 8000d72:   1900        adds    r0, r0, r4
 8000d74:   0080        lsls    r0, r0, #2
 8000d76:   1880        adds    r0, r0, r2
 8000d78:   3004        adds    r0, #4
 8000d7a:   f7ff ffbb   bl  8000cf4 <rtlib::Delegate<void (mcu::stm32g070::Gpio::GpioId)>::operator()(mcu::stm32g070::Gpio::GpioId) const>
 8000d7e:   e7d6        b.n 8000d2e <(anonymous namespace)::CommonISRHandler(unsigned short)+0x12>
}
 8000d80:   bd70        pop {r4, r5, r6, pc}
 8000d82:   46c0        nop         @ (mov r8, r8)
 8000d84:   08013ccc    .word   0x08013ccc
 8000d88:   08013ce0    .word   0x08013ce0
 8000d8c:   08013dc4    .word   0x08013dc4
 8000d90:   40021800    .word   0x40021800
 8000d94:   20000734    .word   0x20000734

Índice mascarado:

08000710 <(anonymous namespace)::CommonISRHandler(unsigned short)>:
void CommonISRHandler([[maybe_unused]] uint16_t exti_set_mask) {
 8000710:   b570        push    {r4, r5, r6, lr}
 8000712:   0005        movs    r5, r0
  while (exti_set_mask) {
 8000714:   e00b        b.n 800072e <(anonymous namespace)::CommonISRHandler(unsigned short)+0x1e>
    EXTI->RPR1 &= (1 << index);
 8000716:   4a14        ldr r2, [pc, #80]   @ (8000768 <(anonymous namespace)::CommonISRHandler(unsigned short)+0x58>)
 8000718:   68d1        ldr r1, [r2, #12]
 800071a:   2301        movs    r3, #1
 800071c:   40a3        lsls    r3, r4
 800071e:   4019        ands    r1, r3
 8000720:   60d1        str r1, [r2, #12]
    EXTI->FPR1 &= (1 << index);
 8000722:   6911        ldr r1, [r2, #16]
 8000724:   4019        ands    r1, r3
 8000726:   6111        str r1, [r2, #16]
    exti_set_mask &= ~(1 << index);
 8000728:   43db        mvns    r3, r3
 800072a:   b21b        sxth    r3, r3
 800072c:   401d        ands    r5, r3
  while (exti_set_mask) {
 800072e:   2d00        cmp r5, #0
 8000730:   d018        beq.n   8000764 <(anonymous namespace)::CommonISRHandler(unsigned short)+0x54>
    uint8_t index = __builtin_ctz(exti_set_mask) & 0xf;
 8000732:   0028        movs    r0, r5
 8000734:   f7ff fcc0   bl  80000b8 <__ctzsi2>
 8000738:   240f        movs    r4, #15
 800073a:   4004        ands    r4, r0
    return stub_ptr != nullptr;
 800073c:   4b0b        ldr r3, [pc, #44]   @ (800076c <(anonymous namespace)::CommonISRHandler(unsigned short)+0x5c>)
 800073e:   0062        lsls    r2, r4, #1
 8000740:   1912        adds    r2, r2, r4
 8000742:   0092        lsls    r2, r2, #2
 8000744:   189b        adds    r3, r3, r2
 8000746:   689b        ldr r3, [r3, #8]
    if (gpio_irq_info.callback.IsValid()) {
 8000748:   2b00        cmp r3, #0
 800074a:   d0e4        beq.n   8000716 <(anonymous namespace)::CommonISRHandler(unsigned short)+0x6>
      gpio_irq_info.callback(gpio_irq_info.pin);
 800074c:   4a07        ldr r2, [pc, #28]   @ (800076c <(anonymous namespace)::CommonISRHandler(unsigned short)+0x5c>)
 800074e:   0060        lsls    r0, r4, #1
 8000750:   1901        adds    r1, r0, r4
 8000752:   0089        lsls    r1, r1, #2
 8000754:   5c89        ldrb    r1, [r1, r2]
 8000756:   1900        adds    r0, r0, r4
 8000758:   0080        lsls    r0, r0, #2
 800075a:   1880        adds    r0, r0, r2
 800075c:   3004        adds    r0, #4
 800075e:   f7ff ffc3   bl  80006e8 <rtlib::Delegate<void (mcu::stm32g070::Gpio::GpioId)>::operator()(mcu::stm32g070::Gpio::GpioId) const>
 8000762:   e7d8        b.n 8000716 <(anonymous namespace)::CommonISRHandler(unsigned short)+0x6>
}
 8000764:   bd70        pop {r4, r5, r6, pc}
 8000766:   46c0        nop         @ (mov r8, r8)
 8000768:   40021800    .word   0x40021800
 800076c:   2000005c    .word   0x2000005c

EDIT #2 , Alguns bons comentários até agora, obrigado. Minha razão para acreditar que exceções estão sendo puxadas é por causa da presença de muitas funções no objdump não mascarado que não estão presentes na saída do objdump mascarado ( grep -i exception, grep -i throw):

08000438 <_Unwind_RaiseException>:
 800045e:       f009 f831       bl      80094c4 <__gnu_Unwind_RaiseException>
 8001764:       f007 fb0e       bl      8008d84 <__cxa_current_exception_type>
080089d8 <__cxxabiv1::__is_gxx_exception_class(char*)>:
 80089e0:       d000            beq.n   80089e4 <__cxxabiv1::__is_gxx_exception_class(char*)+0xc>
 80089e8:       d1fb            bne.n   80089e2 <__cxxabiv1::__is_gxx_exception_class(char*)+0xa>
 80089ee:       d1f8            bne.n   80089e2 <__cxxabiv1::__is_gxx_exception_class(char*)+0xa>
 80089f4:       d1f5            bne.n   80089e2 <__cxxabiv1::__is_gxx_exception_class(char*)+0xa>
 80089fa:       d1f2            bne.n   80089e2 <__cxxabiv1::__is_gxx_exception_class(char*)+0xa>
 8008a00:       d1ef            bne.n   80089e2 <__cxxabiv1::__is_gxx_exception_class(char*)+0xa>
 8008a06:       d1ec            bne.n   80089e2 <__cxxabiv1::__is_gxx_exception_class(char*)+0xa>
 8008a12:       e7e6            b.n     80089e2 <__cxxabiv1::__is_gxx_exception_class(char*)+0xa>
 8008a20:       f7ff ffda       bl      80089d8 <__cxxabiv1::__is_gxx_exception_class(char*)>
 8008a44:       f7ff ffc8       bl      80089d8 <__cxxabiv1::__is_gxx_exception_class(char*)>
 8008b02:       f000 fad3       bl      80090ac <__cxa_allocate_exception>
 8008bc0:       f000 fce6       bl      8009590 <_Unwind_DeleteException>
 8008c2c:       f000 fcb0       bl      8009590 <_Unwind_DeleteException>
08008c34 <std::bad_exception::~bad_exception()>:
08008c38 <transaction clone for std::bad_exception::what() const>:
 8008c38:       4800            ldr     r0, [pc, #0]    @ (8008c3c <transaction clone for std::bad_exception::what() const+0x4>)
08008c40 <std::bad_exception::~bad_exception()>:
08008c60 <__gxx_exception_cleanup(_Unwind_Reason_Code, _Unwind_Control_Block*)>:
 8008c64:       d812            bhi.n   8008c8c <__gxx_exception_cleanup(_Unwind_Reason_Code, _Unwind_Control_Block*)+0x2c>
 8008c72:       d000            beq.n   8008c76 <__gxx_exception_cleanup(_Unwind_Reason_Code, _Unwind_Control_Block*)+0x16>
 8008c7e:       d001            beq.n   8008c84 <__gxx_exception_cleanup(_Unwind_Reason_Code, _Unwind_Control_Block*)+0x24>
 8008c86:       f000 fa27       bl      80090d8 <__cxa_free_exception>
 8008c8a:       e7f3            b.n     8008c74 <__gxx_exception_cleanup(_Unwind_Reason_Code, _Unwind_Control_Block*)+0x14>
08008c94 <__cxa_init_primary_exception>:
 8008cd0:       4b02            ldr     r3, [pc, #8]    @ (8008cdc <__cxa_init_primary_exception+0x48>)
 8008cf8:       f7ff ffcc       bl      8008c94 <__cxa_init_primary_exception>
 8008d06:       f7f7 fb97       bl      8000438 <_Unwind_RaiseException>
08008d84 <__cxa_current_exception_type>:
 8008d8e:       d004            beq.n   8008d9a <__cxa_current_exception_type+0x16>
 8008d96:       d001            beq.n   8008d9c <__cxa_current_exception_type+0x18>
 8008da0:       e7fa            b.n     8008d98 <__cxa_current_exception_type+0x14>
080090ac <__cxa_allocate_exception>:
 80090b8:       d007            beq.n   80090ca <__cxa_allocate_exception+0x1e>
 80090d2:       d1f2            bne.n   80090ba <__cxa_allocate_exception+0xe>
080090d8 <__cxa_free_exception>:
 80090d8:       4b07            ldr     r3, [pc, #28]   @ (80090f8 <__cxa_free_exception+0x20>)
 80090e6:       d201            bcs.n   80090ec <__cxa_free_exception+0x14>
 80090ea:       d302            bcc.n   80090f2 <__cxa_free_exception+0x1a>
 80090f6:       e7fb            b.n     80090f0 <__cxa_free_exception+0x18>
080094c4 <__gnu_Unwind_RaiseException>:
 80094e0:       e006            b.n     80094f0 <__gnu_Unwind_RaiseException+0x2c>
 80094ee:       d108            bne.n   8009502 <__gnu_Unwind_RaiseException+0x3e>
 80094fa:       d0f2            beq.n   80094e2 <__gnu_Unwind_RaiseException+0x1e>
 800950a:       d1f7            bne.n   80094fc <__gnu_Unwind_RaiseException+0x38>
 8009584:       f7ff ff9e       bl      80094c4 <__gnu_Unwind_RaiseException>
08009590 <_Unwind_DeleteException>:
 8009598:       d001            beq.n   800959e <_Unwind_DeleteException+0xe>

08000498 <_Unwind_Resume_or_Rethrow>:
 80004be:       f009 f857       bl      8009570 <__gnu_Unwind_Resume_or_Rethrow>
 80017c6:       f007 faa5       bl      8008d14 <__cxa_rethrow>
 8008ad0:       f000 f920       bl      8008d14 <__cxa_rethrow>
 8008b0e:       f000 f8e7       bl      8008ce0 <__cxa_throw>
08008ce0 <__cxa_throw>:
08008d14 <__cxa_rethrow>:
 8008d24:       d00c            beq.n   8008d40 <__cxa_rethrow+0x2c>
 8008d2c:       d00a            beq.n   8008d44 <__cxa_rethrow+0x30>
 8008d36:       f7f7 fbaf       bl      8000498 <_Unwind_Resume_or_Rethrow>
 8008d4a:       d1f0            bne.n   8008d2e <__cxa_rethrow+0x1a>
 8008d52:       d1ec            bne.n   8008d2e <__cxa_rethrow+0x1a>
 8008d5a:       d1e8            bne.n   8008d2e <__cxa_rethrow+0x1a>
 8008d62:       d1e4            bne.n   8008d2e <__cxa_rethrow+0x1a>
 8008d6a:       d1e0            bne.n   8008d2e <__cxa_rethrow+0x1a>
 8008d72:       d1dc            bne.n   8008d2e <__cxa_rethrow+0x1a>
 8008d7a:       d8d8            bhi.n   8008d2e <__cxa_rethrow+0x1a>
 8008d82:       e7d6            b.n     8008d32 <__cxa_rethrow+0x1e>
08009570 <__gnu_Unwind_Resume_or_Rethrow>:
 8009576:       d005            beq.n   8009584 <__gnu_Unwind_Resume_or_Rethrow+0x14>
 8009588:       e7fb            b.n     8009582 <__gnu_Unwind_Resume_or_Rethrow+0x12>
c++
  • 2 respostas
  • 191 Views

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve