ThrowTheSwitch / CException

Lightweight exception implementation for C
http://throwtheswitch.org
MIT License
326 stars 66 forks source link

Microchip XC16: some tests fail #18

Closed matteofranceschini closed 8 months ago

matteofranceschini commented 4 years ago

Hi! I'm trying to use your library on some test project to learn something new, but with a simple "main" that only does this:

int main(void)
{
CEXCEPTION_T e = CEXCEPTION_NONE;
    Try{
        SYSTEM_Initialize();
    }

    Catch(e)
    {
        /*Initialization error*/
        LED_RED2_SetHigh();
        while (1);
    };
return 0;
}

with SYSTEM_Initialize() that has

if (0)
    Throw(E_ERROR_INITIALIZING);

it continuously goes into the catch, with or without "e" initialized and with or without the throw commented out (that shouldn't be called, anyway).

I tried also to debug it from MPLABX v5.35, XC16 V1.50 and after i get out from System_Initialize() i still have e=CEXCEPTION_NONE, when initialized, or e=0xFFFF when not initialized but I don't understand why it goes into the catch anyway.

I then tried to run your test (the one included with your library), and luckily it fails in the same way (at least, I have some correlation):

-------------------
FAILED TEST SUMMARY
-------------------
[test_CException.c]
  Test: test_BasicTryDoesNothingIfNoThrow
  At line (28): "Should Not Enter Catch If Not Thrown"

  Test: test_BasicThrowAndCatch_WithMiniSyntax
  At line (72): "I shouldn't be caught because there was no throw"

  Test: test_ThrowAndCatchFromASubFunctionAndNoRethrowToCatchInRootFunc
  At line (178): "Should Not Have Re-thrown Error (it should have already been caught)"

  Test: test_CanHaveNestedTryBlocksInASingleFunction_ThrowInside
  At line (275): "Should Have Been Caught By Inside Catch"

  Test: test_CanHaveNestedTryBlocksInASingleFunction_ThrowOutside
  At line (295): "Should Not Be Caught Here"

  Test: test_AThrowWithoutATryCatchWillUseDefaultHandlerIfSpecified
  At line (317): "Expected FALSE Was TRUE"

  Test: test_AThrowWithoutOutsideATryCatchWillUseDefaultHandlerEvenAfterTryCatch
  At line (340): "Expected FALSE Was TRUE"

  Test: test_AbilityToExitTryWithoutThrowingAnError
  At line (358): "Should Not Have Been Caught"

  Test: test_AbilityToExitTryWillOnlyExitOneLevel
  At line (380): "Should Not Have Been Caught By Inside"

The first test does exactly what my main does, therefore I expected this behavior. For reference, I'm using ceedling (locally initialized with its libraries, CException included) with this project yaml:

# Notes:
# Trying to use ceedling with XC16 and DSPIC33ck

:project:
  :use_exceptions: TRUE
  :use_test_preprocessor: TRUE
  :use_auxiliary_dependencies: TRUE
  :build_root: build
  :release_build: TRUE
  :test_file_prefix: test_

:release_build:
 :output: upx_brain.out
 :use_assembly: FALSE

:environment:

:extension:
  :executable: .out

:paths:
  :test:
    - +:test/**
    - -:test/support
  :source:
    - src/**
    - -:src/build/**
    - -:src/dist/**
    - -:src/nbproject/**
    - -:src/debug/*
  :support:
    - test/support

:defines:
  # in order to add common defines:
  #  1) remove the trailing [] from the :common: section
  #  2) add entries to the :common: section (e.g. :test: has TEST defined)
  :commmon: &common_defines
    - __dsPIC33CK64MP103__
    - UNITY_INT_WIDTH=16
    - UNITY_POINTER_WIDTH=16
    - CMOCK_MEM_INDEX_TYPE=uint16_t
    - CMOCK_MEM_PTR_AS_INT=uint16_t
    - CMOCK_MEM_ALIGN=1
    - CMOCK_MEM_SIZE=4096
  :test:
    - *common_defines
    - TEST
  :test_preprocess:
    - *common_defines
    - TEST

:cmock:
  :mock_prefix: mock_
  :when_no_prototypes: :warn
  :enforce_strict_ordering: TRUE
  :plugins:
    - :ignore
    - :callback
  :treat_as:
    uint8:    HEX8
    uint16:   HEX16
    uint32:   UINT32
    int8:     INT8
    bool:     UINT8

:tools:
  :test_compiler:
    :executable: xc16-gcc
    :arguments:
      - -mcpu=33CK64MP103
      - -x c
      - -c
      - "${1}"
      - -o "${2}"
      - -D$: COLLECTION_DEFINES_TEST_AND_VENDOR
      - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR
      - -Wall
      #- -Werror  # We can't keep this on during test becuase of a CMock pointer issue
      - -O0
      - -mlarge-code
      - -mlarge-arrays
  :test_linker:
    :executable: xc16-gcc
    :arguments:
      - -mcpu=33CK64MP103
      - ${1}
      - -O0
      - -o "./build/release/TestBuild.out"
      - -Wl,-Tp33CK64MP103.gld,-Map=./build/release/TestOutput.map,--report-mem
  :test_fixture:
    :executable: ruby
    :name: "Microchip simulator test fixture"
    :stderr_redirect: :unix #inform Ceedling what model of $stderr capture to use
    :arguments:
      - test/simulation/start_sim.rb #Chiama il simulatore con le impostazioni per il dspic memorizzate nel .txt nella stessa cartella

  :release_compiler:
    :executable: xc16-gcc
    :arguments:
      - -mcpu=33CK64MP103
      - -x c
      - -c
      - "${1}"
      - -o "${2}"
      - -I"$": COLLECTION_PATHS_SOURCE_INCLUDE_VENDOR
      - -I"$": COLLECTION_PATHS_RELEASE_TOOLCHAIN_INCLUDE
      - -D$: COLLECTION_DEFINES_RELEASE_AND_VENDOR
      - -Wall
      - -Werror
      - -O0
      - -mlarge-code
      - -mlarge-arrays
  :release_linker:
    :executable: xc16-gcc
    :arguments:
      - -mcpu=33CK64MP103
      - ${1}
      - -o "${2}"
      - -Wl,-Tp33CK64MP103.gld,-Map=./build/release/MyPicApp.map,--report-mem

:module_generator:
        :project_root: ./
        :source_root: src/
        :test_root: test/
        :naming: "camel"

:plugins:
  :load_paths:
    - vendor/ceedling/plugins
  :enabled:
    - stdout_pretty_tests_report
    - module_generator
...

and calling the MDB simulator with this code:

OUT_FILE = "build/release/out.txt"
File.delete OUT_FILE if File.exists? OUT_FILE 
response = `mdb ./test/simulation/simulator_dspic.txt`
if File.exists? OUT_FILE 
    file_contents = File.read OUT_FILE
    file_contents.gsub!("\r\n", "\n")
    STDOUT.print file_contents
else
    puts "Cannot find file #{OUT_FILE}"
end

That calls these commands:

Device dsPIC33CK64MP103
Hwtool SIM
set oscillator.frequency 8
set oscillator.frequencyunit Mega
set oscillator.rcfrequency 250
set oscillator.rcfrequencyunit Kilo
Set uart1io.uartioenabled true
Set uart1io.output file
Set uart1io.outputfile "./build/release/out.txt"
Program "./build/release/TestBuild.out"
Reset
Sleep 500
Run
Wait 120000
Quit

Any help is appreciated, I'd love to use your libraries in my projects :)

EDIT: I initially had "use exceptions: FALSE" with the manually added path for tests pointing to the "vendor" folder (see edit history). By changing "use exceptions" true and erasing the path to "vendor" the test worsened the result:

-------------------
FAILED TEST SUMMARY
-------------------
[test_CException.c]
  Test: test_BasicTryDoesNothingIfNoThrow
  At line (28): "Should Not Enter Catch If Not Thrown"

  Test: test_BasicThrowAndCatch
  At line (84): "Expected 0x5A5A5A5A Was 0x00008B97. Unhandled Exception!"

  Test: test_BasicThrowAndCatch_WithMiniSyntax
  At line (72): "I shouldn't be caught because there was no throw"

  Test: test_VerifyVolatilesSurviveThrowAndCatch
  At line (84): "Expected 0x5A5A5A5A Was 0x00008B97. Unhandled Exception!"

  Test: test_ThrowFromASubFunctionAndCatchInRootFunc
  At line (84): "Expected 0x5A5A5A5A Was 0x00008B97. Unhandled Exception!"

  Test: test_ThrowAndCatchFromASubFunctionAndRethrowToCatchInRootFunc
  At line (84): "Expected 0x5A5A5A5A Was 0x00008B97. Unhandled Exception!"

  Test: test_ThrowAndCatchFromASubFunctionAndNoRethrowToCatchInRootFunc
  At line (178): "Should Not Have Re-thrown Error (it should have already been caught)"

  Test: test_ThrowAnErrorThenEnterATryBlockFromWithinCatch_VerifyThisDoesntCorruptExceptionId
  At line (84): "Expected 0x5A5A5A5A Was 0x00008B97. Unhandled Exception!"

  Test: test_ThrowAnErrorThenEnterATryBlockFromWithinCatch_VerifyThatEachExceptionIdIndependent
  At line (84): "Expected 0x5A5A5A5A Was 0x00008B97. Unhandled Exception!"

  Test: test_CanHaveMultipleTryBlocksInASingleFunction
  At line (84): "Expected 0x5A5A5A5A Was 0x00008B97. Unhandled Exception!"

  Test: test_CanHaveNestedTryBlocksInASingleFunction_ThrowInside
  At line (275): "Should Have Been Caught By Inside Catch"

  Test: test_CanHaveNestedTryBlocksInASingleFunction_ThrowOutside
  At line (295): "Should Not Be Caught Here"

  Test: test_AThrowWithoutATryCatchWillUseDefaultHandlerIfSpecified
  At line (317): "Expected FALSE Was TRUE"

  Test: test_AThrowWithoutOutsideATryCatchWillUseDefaultHandlerEvenAfterTryCatch
  At line (340): "Expected FALSE Was TRUE"

  Test: test_AbilityToExitTryWithoutThrowingAnError
  At line (358): "Should Not Have Been Caught"

  Test: test_AbilityToExitTryWillOnlyExitOneLevel
  At line (380): "Should Not Have Been Caught By Inside"
deltalejo commented 4 years ago

The compiler says: "large integer implicitly truncated to unsigned type". Try defining CEXCEPTION_NONE as a 16-bit unsigned integer, for example 0x5A5A.

mvandervoord commented 3 years ago

@matteofranceschini -- I'm wondering if @deltalejo 's advice solved your problem? I realize this was a long time ago and you've likely moved on to other solutions if you were not able to get this to work... but I'd appreciate knowing if we have a problem that needs to be investigated here.

matteofranceschini commented 3 years ago

Hey! I actually gave it a try, but it didn't work out of the box. I'll probably make some tests in the near future: I'm planning to get back on this project in the next month or so :)

I'll give more feedback about it! :)

tyler-macinnis commented 1 year ago

I had a similar error "Expected 0x5A5A5A5A Was 0x00000000. Unhandled Exception!" and was able to solve it by putting the following in a support file.

#define CEXCEPTION_NONE (0x00000000)

So I imagine if you did the same, but defined it to 0x00008B97 that it would solve it.