%---------------------------------------------------------------------------% % vim: ts=4 sw=4 et ft=mercury %---------------------------------------------------------------------------% % % The following program used to expose a bug in the runtime's handling % of deep profiled code. When compiled in a deep profiling grade at -O2 % or below it used to abort with a segmentation fault. % % The problem was caused by the code in builtin.{unify, compare} for du types % having inappropriate references to the proc layout structures of the dummy % unify and compare predicates for the dummy type builtin.user_by_rtti. If the % first call to builtin.{unify, compare} at a given call site had the equality % pretest of the two arguments succeed, this used to fill in the call site % dynamic structure with a pointer to the proc dynamic structure of this dummy % predicate, leading later calls through that call site to refer to the wrong % data structure. :- module profdeep_seg_fault. :- interface. :- import_module io. :- pred main(io::di, io::uo) is det. :- implementation. :- type list(T) ---> [] ; [T | list(T)]. :- type t_type ---> t_bool ; t_set(t_type) ; t_list(t_type) ; t_enum(string) ; t_typevar(string). :- type t_sig ---> t_sig(list(t_type), t_type). :- type type_inst ---> ti_par_bool ; ti_par_typevar(string). :- type ti_sig ---> ti_sig(list(type_inst), type_inst). main(!IO) :- A = [ ti_sig([ti_par_bool], ti_par_bool), ti_sig([ti_par_bool], ti_par_bool) ], B = [ ti_sig([ti_par_typevar("FOO")], ti_par_bool), ti_sig([ti_par_typevar("BAR")], ti_par_bool) ], AllBuiltinSigs = [A, B], add_sigs_to_sym(AllBuiltinSigs, [], S), io.write(S, !IO), io.nl(!IO). :- pred add_sigs_to_sym(list(list(ti_sig))::in, list(t_sig)::in, list(t_sig)::out) is det. add_sigs_to_sym([], S, S). add_sigs_to_sym([TISigs | TISigs0], S0, S) :- ti_sigs_to_t_sigs(TISigs, TSigs0), insertion_sort(TSigs0, [], TSigs), append_type_sigs(TSigs, S0, S1), add_sigs_to_sym(TISigs0, S1, S). :- pred ti_sigs_to_t_sigs(list(ti_sig)::in, list(t_sig)::out) is det. ti_sigs_to_t_sigs([], []). ti_sigs_to_t_sigs([X | Xs], [Y | Ys]) :- X = ti_sig(ArgTIs, RetTI), type_insts_to_t_types(ArgTIs, ArgTs), ( RetTI = ti_par_bool, RetT = t_bool ; RetTI = ti_par_typevar(V), RetT = t_typevar(V) ), Y = t_sig(ArgTs, RetT), ti_sigs_to_t_sigs(Xs, Ys). :- pred type_insts_to_t_types(list(type_inst)::in, list(t_type)::out) is det. type_insts_to_t_types([], []). type_insts_to_t_types([X | Xs], [Y | Ys]) :- ( X = ti_par_bool, Y = t_bool ; X = ti_par_typevar(V), Y = t_typevar(V) ), type_insts_to_t_types(Xs, Ys). :- pred append_type_sigs(list(t_sig)::in, list(t_sig)::in, list(t_sig)::out) is det. append_type_sigs([], Zs, Zs). append_type_sigs([X | Xs], Ys, [X | Zs]) :- append_type_sigs(Xs, Ys, Zs). :- pred insertion_sort(list(t_sig)::in, list(t_sig)::in, list(t_sig)::out) is det. insertion_sort([], Zs, Zs). insertion_sort([X | Xs], Ys0, Zs) :- insert(X, Ys0, Ys), insertion_sort(Xs, Ys, Zs). :- pred insert(t_sig::in, list(t_sig)::in, list(t_sig)::out) is det. insert(X, [], [X]). insert(X, [Y | Ys], Zs) :- ( compare(Res, X, Y), Res = (>) -> insert(X, Ys, Zs0), Zs = [Y | Zs0] ; Zs = [X, Y | Ys] ).