Skip to content

Commit

Permalink
debug: Prepare to let the app own stderr
Browse files Browse the repository at this point in the history
The application should own stdout/stderr. This is especially important
when building CLI applications (like pillar, ecstatic, etc) and having
none Smalltalker use them.

Introduce a VM_ERR() function to return a shared FILE* that can be
used for error logging.

For plugins we will need to extend VirtualMachine to carry a pointer
to the VM_ERR method.
  • Loading branch information
zecke committed May 4, 2019
1 parent 1d9c8bc commit 4733547
Show file tree
Hide file tree
Showing 17 changed files with 139 additions and 114 deletions.
2 changes: 1 addition & 1 deletion build.macos32x86/common/Makefile.vm
Expand Up @@ -60,7 +60,7 @@ OSXSRC=$(wildcard $(OSXDIR)/*.c) $(wildcard $(OSXDIR)/*.m) \
$(wildcard $(OSXCLASSESDIR)/*.c) $(wildcard $(OSXCLASSESDIR)/*.m)
OSXSRC:=$(filter-out $(XEX),$(OSXSRC))
UNIXSRC:=$(addprefix $(UNIXVMDIR)/,aio.c sqUnixHeartbeat.c sqUnixSpurMemory.c \
sqUnixThreads.c sqUnixVMProfile.c)
sqUnixThreads.c sqUnixVMProfile.c debug.c)
VMSRC:= $(MAKERSRC) $(CROSSSRC) $(OSXSRC) $(UNIXSRC)
VMOBJ:= $(notdir $(VMSRC))
VMOBJ:= $(VMOBJ:.c=.o)
Expand Down
2 changes: 1 addition & 1 deletion build.macos64x64/common/Makefile.vm
Expand Up @@ -60,7 +60,7 @@ OSXSRC=$(wildcard $(OSXDIR)/*.c) $(wildcard $(OSXDIR)/*.m) \
$(wildcard $(OSXCLASSESDIR)/*.c) $(wildcard $(OSXCLASSESDIR)/*.m)
OSXSRC:=$(filter-out $(XEX),$(OSXSRC))
UNIXSRC:=$(addprefix $(UNIXVMDIR)/,aio.c sqUnixHeartbeat.c sqUnixSpurMemory.c \
sqUnixThreads.c sqUnixVMProfile.c)
sqUnixThreads.c sqUnixVMProfile.c debug.c)
VMSRC:= $(MAKERSRC) $(CROSSSRC) $(OSXSRC) $(UNIXSRC)
VMOBJ:= $(notdir $(VMSRC))
VMOBJ:= $(VMOBJ:.c=.o)
Expand Down
7 changes: 7 additions & 0 deletions platforms/Cross/vm/sq.h
Expand Up @@ -651,4 +651,11 @@ sqInt ioFreeModule(void *moduleHandle);
/* The Squeak version from which this interpreter was generated. */
extern const char *interpreterVersion;

/* Debug helper - don't print to the user console directly */

/*
* FILE pointing to the error output of the VM.
*/
extern FILE *VM_ERR(void);

#endif /* _SQ_H */
5 changes: 5 additions & 0 deletions platforms/iOS/vm/OSX/sqSqueakOSXApplication.m
Expand Up @@ -298,6 +298,10 @@ - (int) parseArgument: (NSString *) argData peek: (char *) peek
return 1;
}
#endif
if ([argData isEqualToString: VMOPTIONOBJ("quiet")]) {
sqSetVmErrFile(fopen("/dev/null", "w"));
return 1;
}

/* Options with arguments */
if (!peek)
Expand Down Expand Up @@ -495,6 +499,7 @@ - (void) usage {

- (void) printUsage {
printf("\nCommon <option>s:\n");
printf(" "VMOPTION("quiet")" don't print debugging messages from the VM\n");
printf(" "VMOPTION("help")" print this help message, then exit\n");
printf(" "VMOPTION("memory")" <size>[mk] use fixed heap size (added to image size)\n");
printf(" "VMOPTION("nohandlers")" disable sigsegv & sigusr1 handlers\n");
Expand Down
6 changes: 3 additions & 3 deletions platforms/unix/misc/threadValidate/sqUnixHeartbeat.c
Expand Up @@ -275,17 +275,17 @@ yieldToHighPriorityTickerThread()

if ((err = pthread_mutex_lock(&yield_mutex))) {
if (err != EDEADLK)
fprintf(stderr,"pthread_mutex_lock yield_mutex %s\n", strerror(err));
fprintf(VM_ERR(),"pthread_mutex_lock yield_mutex %s\n", strerror(err));
}
/* If lock fails then unblockVMThreadAfterYieldToHighPriorityTickerThread
* has locked and we should not block.
*/
if ((err = pthread_mutex_lock(&yield_sync))) {
if (err != EDEADLK)
fprintf(stderr,"pthread_mutex_lock yield_sync %s\n", strerror(err));
fprintf(VM_ERR(),"pthread_mutex_lock yield_sync %s\n", strerror(err));
}
else if ((err = pthread_cond_wait(&yield_cond, &yield_mutex)))
fprintf(stderr,"pthread_cond_wait %s\n", strerror(err));
fprintf(VM_ERR(),"pthread_cond_wait %s\n", strerror(err));
}

/* Private to sqTicker.c checkHighPriorityTickees */
Expand Down
14 changes: 7 additions & 7 deletions platforms/unix/misc/threadValidate/threadValidate.c
Expand Up @@ -79,7 +79,7 @@ printAndQuit()
void
lockedup(int arg)
{
fprintf(stderr,"system locked %s, time not advancing (yield method %s)\n",
fprintf(VM_ERR(),"system locked %s, time not advancing (yield method %s)\n",
arg == SIGINT ? "" : (char *)arg, method);
printf("vm %10lld hp %9lld hp+vm %10lld yields %d (%d,%d,%d) clk hz %ld\n",
vmcount, hpcount, vmcount + hpcount,
Expand Down Expand Up @@ -143,23 +143,23 @@ maybeYield()
case yield_via_wait_signal: { int err;
if ((err = pthread_mutex_lock(&yield_mutex))) {
if (err != EDEADLK)
fprintf(stderr,"pthread_mutex_lock yield_mutex %s\n", strerror(err));
fprintf(VM_ERR(),"pthread_mutex_lock yield_mutex %s\n", strerror(err));
}
else if ((err = pthread_mutex_lock(&yield_sync))) {
if (err != EDEADLK)
fprintf(stderr,"pthread_mutex_lock yield_sync %s\n", strerror(err));
fprintf(VM_ERR(),"pthread_mutex_lock yield_sync %s\n", strerror(err));
}
else {
sqLowLevelMFence();
if (yield
&& (err = pthread_cond_wait(&yield_cond, &yield_mutex)))
fprintf(stderr,"pthread_cond_wait %s\n", strerror(err));
fprintf(VM_ERR(),"pthread_cond_wait %s\n", strerror(err));
}
break;
}

default:
fprintf(stderr,"unrecognized yield method\n");
fprintf(VM_ERR(),"unrecognized yield method\n");
exit(5);
}
}
Expand Down Expand Up @@ -236,7 +236,7 @@ main(int argc, char *argv[])
else if (!strcmp(argv[1],"wait_signal"))
yieldMethod = yield_via_wait_signal;
else {
fprintf(stderr,
fprintf(VM_ERR(),
"usage: %s [none] [sched_yield] [nanosleep] [cond_timedwait] [wait_signal] [yield usecs]\n",
argv[0]);
return 3;
Expand Down Expand Up @@ -281,4 +281,4 @@ ioNumProcessors(void)
}

void
warning(char *msg) { fprintf(stderr,"%s\n", msg); }
warning(char *msg) { fprintf(VM_ERR(),"%s\n", msg); }
29 changes: 15 additions & 14 deletions platforms/unix/vm/aio.c
Expand Up @@ -31,6 +31,7 @@
*/

#include "sqaio.h"
#include "sq.h"

#ifdef HAVE_CONFIG_H

Expand Down Expand Up @@ -99,7 +100,7 @@
#endif /* !HAVE_CONFIG_H */

/* function to inform the VM about idle time */
extern void addIdleUsecs(long idleUsecs);
extern void addIdleUsecs(sqInt idleUsecs);

#if defined(AIO_DEBUG)
long aioLastTick = 0;
Expand All @@ -126,7 +127,7 @@ static fd_set xdMask; /* external descriptor */
static void
undefinedHandler(int fd, void *clientData, int flags)
{
fprintf(stderr, "undefined handler called (fd %d, flags %x)\n", fd, flags);
fprintf(VM_ERR(), "undefined handler called (fd %d, flags %x)\n", fd, flags);
}

#ifdef AIO_DEBUG
Expand Down Expand Up @@ -221,7 +222,7 @@ static int tickCount = 0;
#define TICKS_PER_CHAR 10
#define DO_TICK(bool) \
do if ((bool) && !(++tickCount % TICKS_PER_CHAR)) { \
fprintf(stderr, "\r%c\r", *ticker); \
fprintf(VM_ERR(), "\r%c\r", *ticker); \
if (!*ticker++) ticker= ticks; \
} while (0)

Expand All @@ -232,7 +233,7 @@ aioPoll(long microSeconds)
fd_set rd, wr, ex;
unsigned long long us;

FPRINTF((stderr, "aioPoll(%ld)\n", microSeconds));
FPRINTF((VM_ERR(), "aioPoll(%ld)\n", microSeconds));
DO_TICK(SHOULD_TICK());

/*
Expand Down Expand Up @@ -269,7 +270,7 @@ aioPoll(long microSeconds)
return 0;
}
if (errno && (EINTR != errno)) {
fprintf(stderr, "errno %d\n", errno);
fprintf(VM_ERR(), "errno %d\n", errno);
perror("select");
return 0;
}
Expand Down Expand Up @@ -332,13 +333,13 @@ aioSleepForUsecs(long microSeconds)
void
aioEnable(int fd, void *data, int flags)
{
FPRINTF((stderr, "aioEnable(%d)\n", fd));
FPRINTF((VM_ERR(), "aioEnable(%d)\n", fd));
if (fd < 0) {
FPRINTF((stderr, "aioEnable(%d): IGNORED\n", fd));
FPRINTF((VM_ERR(), "aioEnable(%d): IGNORED\n", fd));
return;
}
if (FD_ISSET(fd, &fdMask)) {
fprintf(stderr, "aioEnable: descriptor %d already enabled\n", fd);
fprintf(VM_ERR(), "aioEnable: descriptor %d already enabled\n", fd);
return;
}
clientData[fd] = data;
Expand Down Expand Up @@ -395,9 +396,9 @@ aioEnable(int fd, void *data, int flags)
void
aioHandle(int fd, aioHandler handlerFn, int mask)
{
FPRINTF((stderr, "aioHandle(%d, %s, %d)\n", fd, handlerName(handlerFn), mask));
FPRINTF((VM_ERR(), "aioHandle(%d, %s, %d)\n", fd, handlerName(handlerFn), mask));
if (fd < 0) {
FPRINTF((stderr, "aioHandle(%d): IGNORED\n", fd));
FPRINTF((VM_ERR(), "aioHandle(%d): IGNORED\n", fd));
return;
}
#undef _DO
Expand All @@ -416,10 +417,10 @@ void
aioSuspend(int fd, int mask)
{
if (fd < 0) {
FPRINTF((stderr, "aioSuspend(%d): IGNORED\n", fd));
FPRINTF((VM_ERR(), "aioSuspend(%d): IGNORED\n", fd));
return;
}
FPRINTF((stderr, "aioSuspend(%d)\n", fd));
FPRINTF((VM_ERR(), "aioSuspend(%d)\n", fd));
#undef _DO
#define _DO(FLAG, TYPE) \
if (mask & FLAG) { \
Expand All @@ -436,10 +437,10 @@ void
aioDisable(int fd)
{
if (fd < 0) {
FPRINTF((stderr, "aioDisable(%d): IGNORED\n", fd));
FPRINTF((VM_ERR(), "aioDisable(%d): IGNORED\n", fd));
return;
}
FPRINTF((stderr, "aioDisable(%d)\n", fd));
FPRINTF((VM_ERR(), "aioDisable(%d)\n", fd));
aioSuspend(fd, AIO_RWX);
FD_CLR(fd, &xdMask);
FD_CLR(fd, &fdMask);
Expand Down
17 changes: 14 additions & 3 deletions platforms/unix/vm/debug.c
@@ -1,4 +1,5 @@
#include "debug.h"
#include "sq.h"

#include <stdio.h>
#include <stdarg.h>
Expand Down Expand Up @@ -32,13 +33,23 @@ void __sq_eprintf(const char *fmt, ...)
char *file= strrchr(__sq_errfile, '/');
file= file ? file + 1 : __sq_errfile;
va_start(ap, fmt);
fprintf(stderr, "%s(%d): %s:\n", file, __sq_errline, __sq_errfunc);
fprintf(stderr, "%s(%d): ", file, __sq_errline);
vfprintf(stderr, fmt, ap);
fprintf(VM_ERR(), "%s(%d): %s:\n", file, __sq_errline, __sq_errfunc);
fprintf(VM_ERR(), "%s(%d): ", file, __sq_errline);
vfprintf(VM_ERR(), fmt, ap);
va_end(ap);
}


void sqDebugAnchor(void)
{
}

static FILE *VM_ERR_FILE = NULL;

FILE *VM_ERR(void)
{
if (!VM_ERR_FILE) {
VM_ERR_FILE = stderr;
}
return VM_ERR_FILE;
}
20 changes: 10 additions & 10 deletions platforms/unix/vm/dlfcn-dyld.c
Expand Up @@ -63,12 +63,12 @@ static const char *dlerror(void)

static void dlUndefined(const char *symbol)
{
fprintf(stderr, "dyld: undefined symbol: %s\n", symbol);
fprintf(VM_ERR(), "dyld: undefined symbol: %s\n", symbol);
}

static NSModule dlMultiple(NSSymbol s, NSModule oldModule, NSModule newModule)
{
DPRINTF((stderr, "dyld: %s: %s previously defined in %s, new definition in %s\n",
DPRINTF((VM_ERR(), "dyld: %s: %s previously defined in %s, new definition in %s\n",
NSNameOfSymbol(s), NSNameOfModule(oldModule), NSNameOfModule(newModule)));
return newModule;
}
Expand All @@ -77,7 +77,7 @@ static void dlLinkEdit(NSLinkEditErrors errorClass, int errorNumber,
const char *fileName, const char *errorString)

{
fprintf(stderr, "dyld: %s: %s\n", fileName, errorString);
fprintf(VM_ERR(), "dyld: %s: %s\n", fileName, errorString);
}

static NSLinkEditErrorHandlers errorHandlers=
Expand Down Expand Up @@ -126,7 +126,7 @@ static void *dlopen(const char *path, int mode)
if (!handle)
dlSetError("could not load shared object: %s", path);

DPRINTF((stderr, "dlopen: %s => %d\n", path, (int)handle));
DPRINTF((VM_ERR(), "dlopen: %s => %d\n", path, (int)handle));

return handle;
}
Expand All @@ -139,17 +139,17 @@ static void *dlsym(void *handle, const char *symbol)

snprintf(_symbol, sizeof(_symbol), "_%s", symbol);

DPRINTF((stderr, "dlsym: looking for %s (%s) in %d\n", symbol, _symbol, (int)handle));
DPRINTF((VM_ERR(), "dlsym: looking for %s (%s) in %d\n", symbol, _symbol, (int)handle));

if (!handle)
{
DPRINTF((stderr, "dlsym: setting app context for this handle\n"));
DPRINTF((VM_ERR(), "dlsym: setting app context for this handle\n"));
handle= DL_APP_CONTEXT;
}

if (DL_APP_CONTEXT == handle)
{
DPRINTF((stderr, "dlsym: looking in app context\n"));
DPRINTF((VM_ERR(), "dlsym: looking in app context\n"));
if (NSIsSymbolNameDefined(_symbol))
nsSymbol= NSLookupAndBindSymbol(_symbol);
}
Expand All @@ -165,15 +165,15 @@ static void *dlsym(void *handle, const char *symbol)
_symbol,
NSLOOKUPSYMBOLINIMAGE_OPTION_BIND
/*| NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR*/);
DPRINTF((stderr, "dlsym: bundle (image) lookup returned %p\n", nsSymbol));
DPRINTF((VM_ERR(), "dlsym: bundle (image) lookup returned %p\n", nsSymbol));
}
else
DPRINTF((stderr, "dlsym: bundle (image) symbol not defined\n"));
DPRINTF((VM_ERR(), "dlsym: bundle (image) symbol not defined\n"));
}
else
{
nsSymbol= NSLookupSymbolInModule(handle, _symbol);
DPRINTF((stderr, "dlsym: dylib (module) lookup returned %p\n", nsSymbol));
DPRINTF((VM_ERR(), "dlsym: dylib (module) lookup returned %p\n", nsSymbol));
}
}

Expand Down
3 changes: 2 additions & 1 deletion platforms/unix/vm/sqUnixCharConv.c
Expand Up @@ -33,6 +33,7 @@
# include "sqMemoryAccess.h"
#endif
#include "sqUnixCharConv.h"
#include "sq.h"

#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -115,7 +116,7 @@ void setEncoding(void **encoding, char *rawName)
}
else
++ap;
fprintf(stderr, "setEncoding: could not set encoding '%s'\n", name);
fprintf(VM_ERR(), "setEncoding: could not set encoding '%s'\n", name);
done:
free(name);
}
Expand Down

0 comments on commit 4733547

Please sign in to comment.