MSP Object instantiation crash

Jul 9, 2011 at 4:34pm

MSP Object instantiation crash

I’m working on an MSP object. I copied the project from a known-good Xcode project and I’ve compared it with the examples, but I keep getting obex errors when I try to load it into Max which, from what I’ve read, usually indicate that there’s something amiss in the setup. The problem is that I’m getting this with a very straightforward setup.

I went through the Xcode project and swapped over everything that had the name of the old project in it, and I’ve cleaned, etc. Can anyone provide some insight?

Here’s the relevant code:
#include “ext.h”
#include “ext_obex.h”
#include “z_dsp.h”

static t_class *foo_class;

typedef struct _foo {

t_pxobject m_obj;
// rest of the structure’s fields
} t_foo;

// Prototypes
t_int *foo_perform(t_int *w);
void foo_dsp(t_foo *x, t_signal **sp, short *count);
void *foo_new(void);
void foo_mode(t_foo *x, int mode);
void foo_assist(t_foo *x, void *b, long m, long a, char *s);
void foo_float(t_foo *x, double f);

int main(void)
{

// NEW METHOD
t_class *c;

c = class_new(“foo~”, (method)foo_new, (method)dsp_free, sizeof(t_foo), NULL, 0);

class_dspinit(c); // new style object version of dsp_initclass();

class_addmethod(c, (method)foo_dsp,”dsp”, A_CANT, 0);
class_addmethod(c, (method)foo_mode, “mode”, A_LONG, 0);
class_addmethod(c, (method)foo_float, “float”, A_FLOAT, 0);
class_addmethod(c, (method)foo_assist, “assist”, A_CANT, 0);

class_register(CLASS_BOX, c); // register class as a box class
foo_class = c;
return 0;
}

void *foo_new(void) {
t_foo *c = (t_foo *) object_alloc(foo_class);

dsp_setup((t_pxobject *)c,3); // Three inlets: input, freq, res
// Always crashes here…

// Create outlet
outlet_new((t_object *)c, “signal”); // Create outlet

//c->freq = 60.f;
//c->res = 0.5;

return (c);

}

t_int *foo_perform(t_int *w) {
return (w+6)
}

void foo_dsp(t_foo *x, t_signal **sp, short *count) {

x->smprate = sp[0]->s_sr;
x->vecSize = sp[0]->s_n;
x->invsmp = 1./x->vecSize; //
x->invSR = 1.f/sp[0]->s_sr;

dsp_add(foo_perform, 5, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[3]->s_vec,x);
}

Here’s the crash log:
0 com.cycling74.MaxMSP 0x000b7e0c class_obexoffset_get + 6
1 com.cycling74.MaxMSP 0x000b8b8f object_obex_get + 29
2 com.cycling74.MaxMSP 0x000b8beb object_obex_lookup + 39
3 com.cycling74.MaxAPI 0x00ebb9d2 object_obex_lookup + 45
4 com.cycling74.MaxAudioAPI 0x0e591677 z_dsp_setup + 68
5 com.apple.PM_foo_ 0x0f7fbcd2 foo_new + 50

#57935
Jul 9, 2011 at 8:48pm

Hi Peter,

did you try replacing the line


outlet_new((t_object *)c, "signal"); // Create outlet

to


outlet_new((t_pxobject *)c, "signal"); // Create outlet

in your foo_new() method? I’m not sure that helps, just wondering, maybe…

Cheers,
Ádám

#207862
Jul 10, 2011 at 5:15am

I did, but to no avail. Thanks, anyways!

#207863
Jul 10, 2011 at 12:32pm

OK, now that I think on it, that was a quite silly idea. I created a new project and compiled your submitted code, and I can report that the code itself compiles and runs fine.

According to the crash log, it crashes on dsp_setup when it tries to guess the location of the obex member of your struct with class_obexoffset_get (which AFAIK calls the ANSI C offsetof macro). Since this seems to be (at least for me) some sort of aligning issue with the t_foo struct, it gives the impression that t_foo actually contains more fields than those you have posted. Could you please verify this?

Also, did you try copying an SDK-example (after verifying that that particular example compiles fine, of course) and just replacing its code with your one?

It seems an interesting bug, though.

Best,
Ádám

#207864
Jul 11, 2011 at 1:14am

I spent some time debugging it today. You are correct, I have quite a few more fields in the struct. I have two tables in the struct:
float tab[4096];
float ftom_tab[4096];

and the code compiles when I remove the second one. (!?) I went through it methodically, disabled variables one at a time, and that definitely makes the difference between crash and no crash.

I’m new to C (coming from Java), so I suspect I’m making the kind of mistakes that Java won’t allow you to make. It’s probably time to go brush up on pointers…

#207865
Jul 11, 2011 at 5:13am

Hello Peter McCulloch,

I don’t know exactly what is the allowed size limit of the object structure, but it seems 4096 * 2 is too big ; you should allocated memory dynamically in the heap with sysmem_newptr in your myobject_new ( ) function.

typedef struct _myobject {
t_object ob;
double *freq;
} t_myobject;

void *myobject_new (t_symbol *s, long argc, t_atom *argv)
{
...
     x->freq = (double *)sysmem_newptr (sizeof(double) * FREQ_ARRAY_SIZE);
...
}

void myobject_free (t_myobject)
{
...
     sysmem_freeptr (x->freq);
...
}

HTH

#207866
Jul 11, 2011 at 8:07am

If it clarifies, I seem to remember having a similar issue some time ago, and indeed the struct size has a upper limit of something like 32KB.
Someone with wizzo knowledge of SDK dev may correct me if I am wrong.
Regards,
Leigh

#207867
Jul 11, 2011 at 8:52am

That’s correct. Allocating in the yourobject_new() method, freeing in the yourobject_free() method as mentioned by vanille béchamel is the way to go.

#207868
Jul 12, 2011 at 1:50pm

Good to know, and many thanks for everyone who helped me! I’ll try it this afternoon.

#207869
Jul 12, 2011 at 7:06pm

Thanks everyone for the contributions. This did the trick. As a brief follow-up to vanille béchamel’s post: (and for anyone who’s searching this later…)

void myobject_free (t_myobject *x)
{
dsp_free((t_pxobject *)x); // Call this first to prevent max from crashing when freeing while DSP is on
sysmem_freeptr (x->freq);

}

#207870

You must be logged in to reply to this topic.