Skip to content

Meaningful Stack Trace prints #281

@jleben

Description

@jleben

[Issue migrated from SourceForge | ID: 2830776 | Submitted by 'sciss']
[http://sourceforge.net/support/tracker.php?aid=2830776]

Developing medium size or even larger projects with SuperCollider is currently very burdensome because the language does not provide an interactive Debugger with Step-by-Step execution, Breakpoints etc. As a consequence, you really need to rely on the runtime errors printing out useful information.

Unfortunately under some circumstances, the stack trace prints are close to completely useless. In the below example it might be due to Object:perform involved, maybe due to Function nesting, maybe due to execution in a Routine, i don't know - at least the pattern is very common and annoying. I have attached the involved classes albeit you will not be able to compile them without a bunch of other classes, so that it just for reference.

The stack trace i get is like this:

ERROR: Message 'server' not understood.
RECEIVER:
nil
ARGS:
CALL STACK:
DoesNotUnderstandError:reportError 1A1F6830
arg this =
< FunctionDef in Method Wolkenpumpe:prTaskBody > 184EBF70
arg error =
< FunctionDef in Method Wolkenpumpe:prTaskBody > (no arguments or variables)
Float:do 184EBE50
arg this = inf
arg function =
var i = 0.0
Wolkenpumpe:prTaskBody 181167B0
arg this =
var task = [*3]
var delta = 0.0
var trnsTime = 44253.987579680004
Routine:prStart 184EBBB0
arg this =
arg inval = 4.693663166995975

So you don't see anything, except that it was raised somewhere from Wolkenpumpe:prTaskBody... It costs a lot of time to figure out exactly where the exception was raised. In fact, the above trace misses 6 steps. I propose the stack trace should look like this:

ERROR: Message 'server' not understood.
RECEIVER:
nil
ARGS:
CALL STACK:
DoesNotUnderstandError:reportError 1A1F6830
arg this =

NuagesProc:prInitNuagesProc XXXXXXXX
(NuagesProc.sc : Line 95 : 'defWatcher = NuagesSynth...')
...

Meta_NuagesProc:newToBundle XXXXXXXX
(NuagesProc.sc : Line 81 : '^super.new.prInitNuagesP...')
...

NuagesProcCreateTransaction:protPerform XXXXXXXX
(NuagesProcCreateTransaction.sc : Line 53 : 'proc = NuagesProc.newToB...')
...

NuagesTransaction:perform XXXXXXXX
(NuagesTransaction.sc : Line 28 : 'success = this.protPerfo...')
...

Wolkenpumpe:taskInsertGenerator XXXXXXXX
(Wolkenpumpe.sc : Line 442 : 'if( trns.perform( bndl )...')
...

Object:perform XXXXXXXX
(Object.sc : Line 59 : '_ObjectPerform;')
...

Wolkenpumpe:prTaskBody 16D5C450
(Wolkenpumpe.sc : Line 711 : 'this.perform( _task );')
arg this =
var task = [_3]
var delta = 0.0
var trnsTime = 43280.540689662004
...

Of course printing the source code line is a luxury extra that can be omitted. But for example the line numbers are essential. Due to the missing line numbers (and missing method invocation prints) you end up doing this kind of stupidities all over the place:

protPerform { arg bndl, recall;
var clazz, unit, proc;
"----1".postln;
clazz = name.asClass;
if( clazz.isNil, {
(thisMethod.asString ++ " - no generator class '" ++ name ++ "'").error;
^nil;
});
if( recall, { 
unit = nuages.uf.makeUnit( clazz );
}, {
unit = nuages.uf.makeUnit( clazz );
});
"----2".postln;
proc = NuagesProc.newToBundle( bndl, nuages );
"----3".postln;
proc.setUnitToBundle( bndl, unit );
"----4".postln;
vertex = NuagesVertex( proc );
if( recall, {
nuages.persistPut( pVertexID, vertex );
});
nuages.graph.addFirst( vertex );
if( notify, { nuages.tryChanged( \vertexAdded, vertex, metaData )});
^true;
}

prInitNuagesProc { arg bndl, argNuages;
TypeSafe.checkArgClasses( thisMethod, [ bndl, argNuages ], [ OSCBundle, Wolkenpumpe ], [ false, false ]);

"----A".postln;
proxyAudioBusses= [];
weMadeProxyAudioBusses= [];

defWatcher= NuagesSynthDefWatcher.newFrom( nuages.server );
unitAttrMap= IdentityDictionary.new;
mapAttrName= IdentityDictionary.new;

"----B".postln;
this.prInitToBundle( bndl );
"----C".postln;
}

... which is like putting your own line numbers everywhere, until you catch the line that causes the exception. Obviously this costs a lot of time (and you need to remove them afterwards).

Metadata

Metadata

Assignees

No one assigned

    Labels

    comp: sclangsclang C++ implementation (primitives, etc.). for changes to class lib use "comp: class library"enhancementreopen if needed

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions