Commit ab1e183a authored by Simon Marlow's avatar Simon Marlow

add sysErrorBelch() for reporting system call errors

parent ee4d9a57
......@@ -46,6 +46,20 @@ extern void errorBelch(const char *s, ...)
extern void verrorBelch(const char *s, va_list ap);
/*
* An error condition which is caused by and/or can be corrected by
* the user, and which has an associated error condition reported
* by the system (in errno on Unix, and GetLastError() on Windows).
* The system error message is appended to the message generated
* from the supplied format string.
*
* sysErrorBelch() invokes (*sysErrorMsgFn)().
*/
extern void sysErrorBelch(const char *s, ...)
GNUC3_ATTRIBUTE(format (printf, 1, 2));
extern void vsysErrorBelch(const char *s, va_list ap);
/*
* A debugging message. Debugging messages are generated either as a
* virtue of having DEBUG turned on, or by being explicitly selected
......@@ -72,5 +86,6 @@ extern RtsMsgFunction *errorMsgFn;
extern RtsMsgFunction rtsFatalInternalErrorFn;
extern RtsMsgFunction rtsDebugMsgFn;
extern RtsMsgFunction rtsErrorMsgFn;
extern RtsMsgFunction rtsSysErrorMsgFn;
#endif /* RTSMESSAGES_H */
......@@ -337,9 +337,8 @@ allocNew(nat n) {
if(rec->base==0) {
stgFree((void*)rec);
rec=0;
errorBelch(
"getMBlocks: VirtualAlloc MEM_RESERVE %d blocks failed with: %ld\n"
, n, GetLastError());
sysErrorBelch(
"getMBlocks: VirtualAlloc MEM_RESERVE %d blocks failed", n);
} else {
if(allocs==0) {
allocs=rec;
......@@ -451,7 +450,7 @@ commitBlocks(char* base, int size) {
if(size_delta>size) size_delta=size;
temp = VirtualAlloc(base, size_delta, MEM_COMMIT, PAGE_READWRITE);
if(temp==0) {
errorBelch("getMBlocks: VirtualAlloc MEM_COMMIT failed: %ld\n", GetLastError());
sysErrorBelch("getMBlocks: VirtualAlloc MEM_COMMIT failed");
stg_exit(EXIT_FAILURE);
}
size-=size_delta;
......@@ -515,7 +514,7 @@ freeAllMBlocks(void)
it=allocs;
for(; it!=0; ) {
if(!VirtualFree((void*)it->base, 0, MEM_RELEASE)) {
errorBelch("freeAllMBlocks: VirtualFree MEM_RELEASE failed with %ld", GetLastError());
sysErrorBelch("freeAllMBlocks: VirtualFree MEM_RELEASE failed");
stg_exit(EXIT_FAILURE);
}
next = it->next;
......
......@@ -28,6 +28,7 @@
RtsMsgFunction *fatalInternalErrorFn = rtsFatalInternalErrorFn;
RtsMsgFunction *debugMsgFn = rtsDebugMsgFn;
RtsMsgFunction *errorMsgFn = rtsErrorMsgFn;
RtsMsgFunction *sysErrorMsgFn = rtsSysErrorMsgFn;
void
barf(const char*s, ...)
......@@ -67,6 +68,21 @@ verrorBelch(const char*s, va_list ap)
(*errorMsgFn)(s,ap);
}
void
sysErrorBelch(const char*s, ...)
{
va_list ap;
va_start(ap,s);
(*sysErrorMsgFn)(s,ap);
va_end(ap);
}
void
vsysErrorBelch(const char*s, va_list ap)
{
(*sysErrorMsgFn)(s,ap);
}
void
debugBelch(const char*s, ...)
{
......@@ -90,7 +106,7 @@ vdebugBelch(const char*s, va_list ap)
#if defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
static int
isGUIApp()
isGUIApp(void)
{
PIMAGE_DOS_HEADER pDOSHeader;
PIMAGE_NT_HEADERS pPEHeader;
......@@ -177,6 +193,61 @@ rtsErrorMsgFn(const char *s, va_list ap)
}
}
void
rtsSysErrorMsgFn(const char *s, va_list ap)
{
char *syserr;
#if defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &syserr,
0,
NULL );
if (isGUIApp())
{
char buf[BUFSIZE];
int r;
r = vsnprintf(buf, BUFSIZE, s, ap);
if (r > 0 && r < BUFSIZE) {
r = vsnprintf(buf+r, BUFSIZE-r, ": %s", syserr);
MessageBox(NULL /* hWnd */,
buf,
prog_name,
MB_OK | MB_ICONERROR | MB_TASKMODAL
);
}
}
else
#else
syserr = strerror(errno);
// ToDo: use strerror_r() if available
#endif
{
/* don't fflush(stdout); WORKAROUND bug in Linux glibc */
if (prog_argv != NULL && prog_name != NULL) {
fprintf(stderr, "%s: ", prog_name);
}
vfprintf(stderr, s, ap);
if (syserr) {
fprintf(stderr, ": %s\n", syserr);
} else {
fprintf(stderr, "\n");
}
}
#if defined(cygwin32_HOST_OS) || defined (mingw32_HOST_OS)
if (syserr) LocalFree(syserr);
#endif
}
void
rtsDebugMsgFn(const char *s, va_list ap)
{
......
......@@ -283,7 +283,8 @@ startWorkerTask (Capability *cap,
r = createOSThread(&tid, (OSThreadProc *)taskStart, task);
if (r != 0) {
barf("startTask: Can't create new task");
sysErrorBelch("failed to create OS thread");
stg_exit(EXIT_FAILURE);
}
debugTrace(DEBUG_sched, "new worker task (taskCount: %d)", taskCount);
......
......@@ -89,7 +89,7 @@ void getProcessTimes(Ticks *user, Ticks *elapsed)
long ticks;
ticks = sysconf(_SC_CLK_TCK);
if ( ticks == -1 ) {
errorBelch("sysconf\n");
sysErrorBelch("sysconf");
stg_exit(EXIT_FAILURE);
}
ClockFreq = ticks;
......
......@@ -506,7 +506,7 @@ initDefaultHandlers()
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
if (sigaction(SIGINT, &action, &oact) != 0) {
errorBelch("warning: failed to install SIGINT handler");
sysErrorBelch("warning: failed to install SIGINT handler");
}
#if defined(HAVE_SIGINTERRUPT)
......@@ -518,7 +518,7 @@ initDefaultHandlers()
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
if (sigaction(SIGCONT, &action, &oact) != 0) {
errorBelch("warning: failed to install SIGCONT handler");
sysErrorBelch("warning: failed to install SIGCONT handler");
}
// install the SIGFPE handler
......@@ -536,7 +536,7 @@ initDefaultHandlers()
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
if (sigaction(SIGFPE, &action, &oact) != 0) {
errorBelch("warning: failed to install SIGFPE handler");
sysErrorBelch("warning: failed to install SIGFPE handler");
}
#endif
......
......@@ -38,7 +38,8 @@ initCondition( Condition* pCond )
NULL); /* unnamed => process-local. */
if ( h == NULL ) {
errorBelch("initCondition: unable to create");
sysErrorBelch("initCondition: unable to create");
stg_exit(EXIT_FAILURE);
}
*pCond = h;
return;
......@@ -48,7 +49,7 @@ void
closeCondition( Condition* pCond )
{
if ( CloseHandle(*pCond) == 0 ) {
errorBelch("closeCondition: failed to close");
sysErrorBelch("closeCondition: failed to close");
}
return;
}
......@@ -64,7 +65,8 @@ rtsBool
signalCondition ( Condition* pCond )
{
if (SetEvent(*pCond) == 0) {
barf("SetEvent: %d", GetLastError());
sysErrorBelch("SetEvent");
stg_exit(EXIT_FAILURE);
}
return rtsTrue;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment