Enabling floating point exceptions on MinGW GCC? - gcc

How does one enable floating point exceptions on MinGW GCC, where feenableexcept is missing? Even reasonably complete solutions don't actually catch this, though it would appear that they intend to. I would prefer minimal code that is close to whatever future standards will emerge. Preferably, the code should work with and without SSE. A complete solution that shows how to enable the hardware signal, catch it, and reset it is preferable. Compiling cleanly with high optimization levels and full pedantic errors and warnings is a must. The ability to catch multiple times in a unit-test scenario is important. There are several questions that provide partial answers.

This appears to work on my machine. Compile it in MinGW GCC with -fnon-call-exceptions. It isn't fully minimized yet.
#include <xmmintrin.h>
#include <cerrno>
#include <cfenv>
#include <cfloat> //or #include <float.h> // defines _controlfp_s
#include <cmath>
#include <csignal>
#ifdef _WIN32
void feenableexcept(uint16_t fpflags){
/*edit 2015-12-17, my attempt at ASM code was giving me
*problems in more complicated scenarios, so I
*switched to using _controlfp_s. I finally posted it here
*because of the upvote to the ASM version.*/
/*{// http://stackoverflow.com/questions/247053/
uint16_t mask(FE_ALL_EXCEPT & ~fpflags);
asm("fldcw %0" : : "m" (mask) : "cc");
} //https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html */
unsigned int new_word(0);
if (fpflags & FE_INVALID) new_word |= _EM_INVALID;
if (fpflags & FE_DIVBYZERO) new_word |= _EM_ZERODIVIDE;
if (fpflags & FE_OVERFLOW) new_word |= _EM_OVERFLOW;
unsigned int cw(0);
_controlfp_s(&cw,~new_word,_MCW_EM);
}
#endif
void fe_reset_traps(){
std::feclearexcept(FE_ALL_EXCEPT); //clear x87 FE state
#ifdef __SSE__
_MM_SET_EXCEPTION_STATE(0); // clear SSE FE state
#endif
feenableexcept(FE_DIVBYZERO|FE_OVERFLOW|FE_INVALID); // set x87 FE mask
#ifdef __SSE__
//set SSE FE mask (orientation of this command is different than the above)
_MM_SET_EXCEPTION_MASK(_MM_MASK_DENORM |_MM_MASK_UNDERFLOW|_MM_MASK_INEXACT);
#endif
}
void sigfpe_handler(int sig){
std::signal(sig,SIG_DFL); // block signal, if needed
std::cerr<<"A floating point exception was encountered. Exiting.\n";
fe_reset_traps(); // in testing mode the throw may not exit, so reset traps
std::signal(sig,&sigfpe_handler); // reinstall handler
throw std::exception();
}
fe_reset_traps();
std::signal(SIGFPE,&sigfpe_handler); // install handler
std::cerr<<"before\n";
std::cerr<<1.0/0.0<<"\n";
std::cerr<<"should be unreachable\n";
I'm sure it's not perfect. Let's hear what everyone else has to contribute.

Related

Trap memory accesses inside a standard executable built with MinGW

So my problem sounds like this.
I have some platform dependent code (embedded system) which writes to some MMIO locations that are hardcoded at specific addresses.
I compile this code with some management code inside a standard executable (mainly for testing) but also for simulation (because it takes longer to find basic bugs inside the actual HW platform).
To alleviate the hardcoded pointers, i just redefine them to some variables inside the memory pool. And this works really well.
The problem is that there is specific hardware behavior on some of the MMIO locations (w1c for example) which makes "correct" testing hard to impossible.
These are the solutions i thought of:
1 - Somehow redefine the accesses to those registers and try to insert some immediate function to simulate the dynamic behavior. This is not really usable since there are various ways to write to the MMIO locations (pointers and stuff).
2 - Somehow leave the addresses hardcoded and trap the illegal access through a seg fault, find the location that triggered, extract exactly where the access was made, handle and return. I am not really sure how this would work (and even if it's possible).
3 - Use some sort of emulation. This will surely work, but it will void the whole purpose of running fast and native on a standard computer.
4 - Virtualization ?? Probably will take a lot of time to implement. Not really sure if the gain is justifiable.
Does anyone have any idea if this can be accomplished without going too deep? Maybe is there a way to manipulate the compiler in some way to define a memory area for which every access will generate a callback. Not really an expert in x86/gcc stuff.
Edit: It seems that it's not really possible to do this in a platform independent way, and since it will be only windows, i will use the available API (which seems to work as expected). Found this Q here:
Is set single step trap available on win 7?
I will put the whole "simulated" register file inside a number of pages, guard them, and trigger a callback from which i will extract all the necessary info, do my stuff then continue execution.
Thanks all for responding.
I think #2 is the best approach. I routinely use approach #4, but I use it to test code that is running in the kernel, so I need a layer below the kernel to trap and emulate the accesses. Since you have already put your code into a user-mode application, #2 should be simpler.
The answers to this question may provide help in implementing #2. How to write a signal handler to catch SIGSEGV?
What you really want to do, though, is to emulate the memory access and then have the segv handler return to the instruction after the access. This sample code works on Linux. I'm not sure if the behavior it is taking advantage of is undefined, though.
#include <stdint.h>
#include <stdio.h>
#include <signal.h>
#define REG_ADDR ((volatile uint32_t *)0x12340000f000ULL)
static uint32_t read_reg(volatile uint32_t *reg_addr)
{
uint32_t r;
asm("mov (%1), %0" : "=a"(r) : "r"(reg_addr));
return r;
}
static void segv_handler(int, siginfo_t *, void *);
int main()
{
struct sigaction action = { 0, };
action.sa_sigaction = segv_handler;
action.sa_flags = SA_SIGINFO;
sigaction(SIGSEGV, &action, NULL);
// force sigsegv
uint32_t a = read_reg(REG_ADDR);
printf("after segv, a = %d\n", a);
return 0;
}
static void segv_handler(int, siginfo_t *info, void *ucontext_arg)
{
ucontext_t *ucontext = static_cast<ucontext_t *>(ucontext_arg);
ucontext->uc_mcontext.gregs[REG_RAX] = 1234;
ucontext->uc_mcontext.gregs[REG_RIP] += 2;
}
The code to read the register is written in assembly to ensure that both the destination register and the length of the instruction are known.
This is how the Windows version of prl's answer could look like:
#include <stdint.h>
#include <stdio.h>
#include <windows.h>
#define REG_ADDR ((volatile uint32_t *)0x12340000f000ULL)
static uint32_t read_reg(volatile uint32_t *reg_addr)
{
uint32_t r;
asm("mov (%1), %0" : "=a"(r) : "r"(reg_addr));
return r;
}
static LONG WINAPI segv_handler(EXCEPTION_POINTERS *);
int main()
{
SetUnhandledExceptionFilter(segv_handler);
// force sigsegv
uint32_t a = read_reg(REG_ADDR);
printf("after segv, a = %d\n", a);
return 0;
}
static LONG WINAPI segv_handler(EXCEPTION_POINTERS *ep)
{
// only handle read access violation of REG_ADDR
if (ep->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION ||
ep->ExceptionRecord->ExceptionInformation[0] != 0 ||
ep->ExceptionRecord->ExceptionInformation[1] != (ULONG_PTR)REG_ADDR)
return EXCEPTION_CONTINUE_SEARCH;
ep->ContextRecord->Rax = 1234;
ep->ContextRecord->Rip += 2;
return EXCEPTION_CONTINUE_EXECUTION;
}
So, the solution (code snippet) is as follows:
First of all, i have a variable:
__attribute__ ((aligned (4096))) int g_test;
Second, inside my main function, i do the following:
AddVectoredExceptionHandler(1, VectoredHandler);
DWORD old;
VirtualProtect(&g_test, 4096, PAGE_READWRITE | PAGE_GUARD, &old);
The handler looks like this:
LONG WINAPI VectoredHandler(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
static DWORD last_addr;
if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION) {
last_addr = ExceptionInfo->ExceptionRecord->ExceptionInformation[1];
ExceptionInfo->ContextRecord->EFlags |= 0x100; /* Single step to trigger the next one */
return EXCEPTION_CONTINUE_EXECUTION;
}
if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP) {
DWORD old;
VirtualProtect((PVOID)(last_addr & ~PAGE_MASK), 4096, PAGE_READWRITE | PAGE_GUARD, &old);
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
This is only a basic skeleton for the functionality. Basically I guard the page on which the variable resides, i have some linked lists in which i hold pointers to the function and values for the address in question. I check that the fault generating address is inside my list then i trigger the callback.
On first guard hit, the page protection will be disabled by the system, but i can call my PRE_WRITE callback where i can save the variable state. Because a single step is issued through the EFlags, it will be followed immediately by a single step exception (which means that the variable was written), and i can trigger a WRITE callback. All the data required for the operation is contained inside the ExceptionInformation array.
When someone tries to write to that variable:
*(int *)&g_test = 1;
A PRE_WRITE followed by a WRITE will be triggered,
When i do:
int x = *(int *)&g_test;
A READ will be issued.
In this way i can manipulate the data flow in a way that does not require modifications of the original source code.
Note: This is intended to be used as part of a test framework and any penalty hit is deemed acceptable.
For example, W1C (Write 1 to clear) operation can be accomplished:
void MYREG_hook(reg_cbk_t type)
{
/** We need to save the pre-write state
* This is safe since we are assured to be called with
* both PRE_WRITE and WRITE in the correct order
*/
static int pre;
switch (type) {
case REG_READ: /* Called pre-read */
break;
case REG_PRE_WRITE: /* Called pre-write */
pre = g_test;
break;
case REG_WRITE: /* Called after write */
g_test = pre & ~g_test; /* W1C */
break;
default:
break;
}
}
This was possible also with seg-faults on illegal addresses, but i had to issue one for each R/W, and keep track of a "virtual register file" so a bigger penalty hit. In this way i can only guard specific areas of memory or none, depending on the registered monitors.

How to execute a piece of kernel code on all CPUs?

I'm trying to make a kernel module to enable FOP compatibility mode for x87 FPU. This is done via setting bit 2 in IA32_MISC_ENABLE MSR. Here's the code:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/msr-index.h>
#include <asm/msr.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("10110111");
MODULE_DESCRIPTION("Module to enable FOPcode compatibility mode");
MODULE_VERSION("0.1");
static int __init fopCompat_init(void)
{
unsigned long long misc_enable=native_read_msr(MSR_IA32_MISC_ENABLE);
printk(KERN_INFO "Before trying to set FOP_COMPAT, IA32_MISC_ENABLE=%llx,"
" i.e. FOP_COMPAT is %senabled\n"
,misc_enable,misc_enable&MSR_IA32_MISC_ENABLE_X87_COMPAT?"":"NOT ");
wrmsrl(MSR_IA32_MISC_ENABLE,misc_enable|MSR_IA32_MISC_ENABLE_X87_COMPAT);
misc_enable=native_read_msr(MSR_IA32_MISC_ENABLE);
printk(KERN_INFO "Tried to set FOP_COMPAT. Result: IA32_MISC_ENABLE=%llx,"
" i.e. FOP_COMPAT is now %senabled\n"
,misc_enable,misc_enable&MSR_IA32_MISC_ENABLE_X87_COMPAT?"":"NOT ");
return 0;
}
static void __exit fopCompat_exit(void)
{
const unsigned long long misc_enable=native_read_msr(MSR_IA32_MISC_ENABLE);
printk(KERN_INFO "Quitting FOP-compat with IA32_MISC_ENABLE=%llx\n",misc_enable);
if(!(misc_enable & MSR_IA32_MISC_ENABLE_X87_COMPAT))
printk(KERN_INFO "NOTE: seems some CPUs still have to be set up, "
"or compatibility mode will work inconsistently\n");
printk(KERN_INFO "\n");
}
module_init(fopCompat_init);
module_exit(fopCompat_exit);
It seems to work, but on multiple insmod/rmmod cycles I sometimes get dmesg output that the compatibility mode wasn't still enabled, although it was immediately after doing wrmsr. After some thinking I realized that it's because the module code was executed on different logical CPUs (I have Core i7 with 4 cores*HT=8 logical CPUs), so I had a 1/8 chance of getting "enabled" print on doing rmmod. After repeating the cycle for about 20 times I got consistent "enabled" prints, and my userspace application happily works with it.
So now my question is: how can I make my code execute on all logical CPUs present on the system, so as to enable compatibility mode for all of them?
For execute code on every CPU use on_each_cpu function.
Signature:
int on_each_cpu(void (*func) (void *info), void *info, int wait)
Description:
Call a function on all processors.
If wait parameter is non-zero, it waits for function's completion on all CPUs.
Function func shouldn't sleep, but whole on_each_cpu() call shouldn't be done in atomic context.

Should calls to OututDebugString be wrapped in #ifdef DEBUG conditional blocks?

In winbase.h I see the following code, marking OutputDebugStringA/W as procedures rather than conditional macros. Does this mean it is best to wrap calls to these procedures in debug-only conditional blocks to keep production code tight, especially in tight loops?
WINBASEAPI
VOID
WINAPI
OutputDebugStringA(
__in LPCSTR lpOutputString
);
WINBASEAPI
VOID
WINAPI
OutputDebugStringW(
__in LPCWSTR lpOutputString
);
#ifdef UNICODE
#define OutputDebugString OutputDebugStringW
#else
#define OutputDebugString OutputDebugStringA
#endif // !UNICODE
Usually we do something like this:
#if defined (DEBUG) | defined (_DEBUG)
#define DebugOutput(x) OutputDebugString(x)
#else
#define DebugOutput(x)
#endif
DebugOutput will be expanded to nothing in release mode, keeping release binary clean and without #idfef/#endif everywhere in the code.
Note, that it is a good idea to also check if compiler is MSVC (_MSC_VER), so your code could be more portable

USART problems with ATmega16

I have a ATMega16 and have looped the Rx Tx (just connected the Rx to the Tx), to send and receive one char in a loop. But i only seems to be receiving 0x00 instead of the char i send.
I have the CPU configured to 1MHz.
But my thought is that since the Rx and Tx are just looped, it shouldn't matter what speed i set, since both are the same?
So basically, I'm trying to get a LED to flash at PORTC when receiving the correct char.
Here is the code:
#ifndef F_CPU
#define F_CPU 10000000
#endif
#define BAUD 9600
#define BAUDRATE ((F_CPU)/(BAUD*16)-1)
#include <avr/io.h>
#include <util/delay.h>
void uart_init(void){
UBRRH = (BAUDRATE>>8);
UBRRL = BAUDRATE;
UCSRB = (1<<TXEN) | (1<<RXEN);
UCSRC = (1<<URSEL) | (1<<UCSZ0) | (1<<UCSZ1);
}
void uart_transmit (unsigned char data){
while (!(UCSRA & (1<<UDRE)));
UDR = data;
}
unsigned char uart_recive(void){
while(!(UCSRA) & (1<<RXC));
return UDR;
}
int main(void)
{
uart_init();
unsigned char c;
PORTC = 0xff;
DDRC = 0xff;
while(1)
{
_delay_ms(200);
uart_transmit(0x2B);
c = uart_recive();
if(c==0x2B){
PORTC = PORTC ^ 0xff;
}
}
}
Any thoughts of what i am doing wrong?
The code seems right.
Thing you may have to check:
if your baudrate is the one you should have
if you try to send a char like 'p'; now you are sending a '+'
check your port configuration and see if it matches to your configuration
I think the last one is the problem.
You can try this code from ATMega manual:
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
After building your program, go to your port configuration and make sure it it set on 8 bits data format and 2 stop bits. Then test it on you microcontroller and see what happens. Please come back with the result.
Consider real baudrate accuracy. See e.g. http://www.wormfood.net/avrbaudcalc.php?postbitrate=9600&postclock=1, AVR provides 7.5% error for 9600baud # 1MHz clock, which is rather high error. Depend what you are sending and receiving. "Normally" you can see a garbage, if you receive permanently 0x00s it looks like another problem.
your F_CPU is set to 10MHz.
you sad that it is configured to 1Mhz.
Also check your Fuses if you really activated the crystal.
If you just use the internal oscillator: it has a relatively large error so that your UART timings may be broken (i never got problems using internal oscillator for debugging).
Another source of error may be your F_CPU definition. Mostly this Preprocessor constant is defined already (propably also wrong) in Makefile (or in IDE project settings) so your #define in Code has not affect since the #ifndef
PORTC pins(TDI,TMS,TCK,SDA) always high because these pins for JTAG and JTAG is enable by default. if you want to use PORTC in your application you have to Disable the JTAG by setting fuse bit. for atmega16 JTAGEN is fuse bit set it to 1(means unprogrammed). in case of fuse bit 0(means programmed) and 1(means unprogrammed) one more thing if you use more than 8MHz you have to set fuse bit otherwise your program will give unexpected or wrong result thanks.

How to handle seg faults under Windows?

How can a Windows application handle segmentation faults? By 'handle' I mean intercept them and perhaps output a descriptive message. Also, the ability to recover from them would be nice too, but I assume that is too complicated.
Let them crash and let the Windows Error Reporting handle it - under Vista+, you should also consider registering with Restart Manager (http://msdn.microsoft.com/en-us/library/aa373347(VS.85).aspx), so that you have a chance to save out the user's work and restart the application (like what Word/Excel/etc.. does)
Use SEH for early exception handling,
and use SetUnhandledExceptionFilter to show a descriptive message.
If you add the /EHa compiler argument then try {} catch(...) will catch all exceptions for you, including SEH exceptions.
You can also use __try {} __except {} which gives you more flexibility on what to do when an exception is caught. putting an __try {} __except {} on your entire main() function is somewhat equivalent to using SetUnhandeledExceptionFilter().
That being said, you should also use the proper terminology: "seg-fault" is a UNIX term. There are no segmentation faults on Windows. On Windows they are called "Access Violation Exceptions"
C++ self-contained example on how to use SetUnhandledExceptionFilter, triggering a write fault and displaying a nice error message:
#include <windows.h>
#include <sstream>
LONG WINAPI TopLevelExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
{
std::stringstream s;
s << "Fatal: Unhandled exception 0x" << std::hex << pExceptionInfo->ExceptionRecord->ExceptionCode
<< std::endl;
MessageBoxA(NULL, s.str().c_str(), "my application", MB_OK | MB_ICONSTOP);
exit(1);
return EXCEPTION_CONTINUE_SEARCH;
}
int main()
{
SetUnhandledExceptionFilter(TopLevelExceptionHandler);
int *v=0;
v[12] = 0; // should trigger the fault
return 0;
}
Tested successfully with g++ (and should work OK with MSVC++ as well)
What you want to do here depends on what sort of faults you are concerned with. If you have sloppy code that is prone to more or less random General Protection Violations, then #Paul Betts answer is what you need.
If you have code that has a good reason to deference bad pointers, and you want to recover, start from #whunmr's suggestion about SEH. You can handle and indeed recover, if you have clear enough control of your code to know exactly what state it is in at the point of the fault and how to go about recovering.
Similar to Jean-François Fabre solution, but with Posix code in MinGW-w64. But note that the program must exit - it can't recover from the SIGSEGV and continue.
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
void sigHandler(int s)
{
printf("signal %d\n", s);
exit(1);
}
int main()
{
signal(SIGSEGV, sigHandler);
int *v=0;
*v = 0; // trigger the fault
return 0;
}

Resources