Monolithic debug build runs fine, production build hard faults

Hello all,
I am trying to create a workaround currently because after 2 months, it seems this issue is not planned to be addressed anytime soon. I am trying to replace the http posting with bursts of particle publishes where the payload is broken down into 622 character chunks and uploaded (this function is it’s own thread). The code was working sometimes, but most of the time fails with SOS 1 (hard fault) when it comes time to package and upload the data. I tried doing a debug build to see why it was failing, but unfortunately the issue seems to be completely non-present when the firmware is compiled as a monolithic debug build. I am testing using 1.4.2 for both, and am wondering why could this be? What are the differences between a regular build and a debug build (i assumed it was just the ability to output the more detailed logs)? This really has me stumped, so any info or suggestions would be greatly appreciated!

This is a complete W.A.G., but I’m wondering if there is a difference in the optimization that is performed between modular and monolithic builds.

1 Like

Me too! I am hoping to get some details maybe that may allow me to work around any deficiencies of a regular build, or even how I should go about attempting to debug this issue if i can’t replicate it with a build that allows me to collect more detailed info?

Does anybody at all have any information about this? I am still completely stuck with this, however on this page i saw this quote:

Also, because the boundary between Device OS and the user application is removed, it's possible to call more low-level system functions from monolithic builds.

I'm sorry if this is a stupid question, but is there some documentation somewhere about this that I simply can't find? Even just a list of these "low-level system functions" that work in monolithic builds but not modular? If not, does nobody at particle know the answers to these questions? I am really surprised to be completely ignored by particle about this, considering the only reason I'm trying to do this workaround is because of ANOTHER bug which I am being completely ignored about. Again, If there is documentation for details about this, PLEASE point me to it and call me an idiot, because I've been searching for days now.

With modular firmware, every system function that can be called from user firmware must be listed in the lists of exported functions. These are the functions that are documented in the API reference.

With monolithic firmware, every function (that not declared static) can be called from user firmware. This includes a large number of internal functions and also some functions in the underlying SDKs, like the Nordic SDK. There’s no list of these functions because it’s large, and you should not call undocumented function in the system, as they are subject to change.

There are additional sanity checks in debug builds, and because the memory layout is different, it’s possible that memory related bugs (buffer overrun or under-run, using freed memory, etc.) will behave differently.

2 Likes

Thank you for the response! To be clear, I wasn’t asking for a list of these functions in order to try to use any of them, I was asking because I was going to try to see if one of those ‘problem functions’ is being used somewhere in my code or a library I am using. This code works fine on the electron (modular and monolithic), but fails this way on the boron (modular), and when I do a debug build for boron, the code works completely fine, even though I have the electron collecting and storing more than 2x as much data before uploading (I reduced the amount that the boron has to collect while trying to get it working). I really just don’t know where to even go next with troubleshooting here, the issue is not present with the electron, and I can’t reproduce the issue with a debug build on the boron. This firmware does not have any I2C functionality at all, so I’ve ruled that out. The code between the electron and boron is exactly the same, except for an #ifdef around a line with setADCSampleTime because that function isn’t available for the boron, and so because the code works fine I would assume that I am not using an invalid pointer, and also not freeing memory twice, overwriting the end of a block of memory, etc.
I am just desperate for some help here, maybe some difference that someone at particle is aware of that would help me pinpoint why this works on the electron, and on boron with monolithic build, but not on boron with modular build, because as far as I can tell from all available documentation, there is no reason that anything I am doing would work on the electron but not on the boron.