jonathan@comp.vuw.ac.nz (Jonathan) (12/13/88)
Software Versions:: gdb 2.7, with local Pyramid configuration. Symptom:: Gdb gets a fatal signal in length_of_subexp(), around 300 levels of recursion deep. Cause:: Investigation reveals that expout is always filled with zeros. The single parameter to write_exp_elt() (in expread.c) is declared to be a union (union exp_element) of various types. All the actual parameters to write_exp_elt() are not unions; they are instances of the various elementary types that make up the union. This is a well-known no-no on Pyramids, or any other machine that passes structs and unions with different conventions than ints or doubles. Fix-By:: Changing the formal parameter to be the largest possible value (a double) works on the Pyramid, but will fail on machines with distinct conventions for passing doubles and ints as parameters (m68k? Mips r2000? Sparc? Others?). A portable way to fix this is, for every call to write_exp_elt(), to declare a local variable of type enum exp_element, assign the desired parameter to the appropriate field of that union, and pass the union to write_exp_elt. (Or, have a distinct write_exp_elt for each field of the union). Either of these leads to large context diffs. Ugly-Fix:: *** expread.y.Orig Sun May 1 02:18:50 1988 --- expread.y Tue Dec 13 14:39:27 1988 *************** *** 544,552 **** /* Add one element to the end of the expression. */ static void ! write_exp_elt (expelt) ! union exp_element expelt; { if (expout_ptr >= expout_size) { expout_size *= 2; --- 544,557 ---- /* Add one element to the end of the expression. */ static void ! ! write_exp_elt (d) ! double d; /* this should be the largest...*/ { + union exp_element expelt; + + expelt.doubleconst = d; + if (expout_ptr >= expout_size) { expout_size *= 2;