MSP Object instantiation crash

    Jul 09 2011 | 4:34 pm
    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 0x0f7fbcd2 foo_new + 50

    • Jul 09 2011 | 8:48 pm
      Hi Peter,
      did you try replacing the line
      outlet_new((t_object *)c, "signal");	// Create outlet
      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
    • Jul 10 2011 | 5:15 am
      I did, but to no avail. Thanks, anyways!
    • Jul 10 2011 | 12:32 pm
      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
    • Jul 11 2011 | 1:14 am
      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...
    • Jul 11 2011 | 8:07 am
      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
    • Jul 11 2011 | 8:52 am
      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.
    • Jul 12 2011 | 1:50 pm
      Good to know, and many thanks for everyone who helped me! I'll try it this afternoon.
    • Jul 12 2011 | 7:06 pm
      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);