Mikael Magnusson wrote: > Played with gdb reverse debugging a bit and found that at one point > before the crash, we have this somewhat incorrect string built up: > (gdb) p tptr-48 > $28 = 0x6e7560 "if [[ m -eq y ]]; then; : && ! :; select G\305\305 in " The point at which the code starts to go wrong is these lines in text.c: 450 s->code = *state->pc++; 451 s->pop = (WC_LIST_TYPE(s->code) & Z_END); code, which is what was popped from the stack is WC_LIST(type=SYNC, skip=0) - Z_END is not set. A comment in parse.c states: * - if not (type & Z_END), followed by next WC_LIST s->code is WC_END not WC_LIST. It doesn't seem valid to check WC_LIST_TYPE for that. We now iterate back round the loop picking up the garbage WC_SELECT(type=pparam, skip=27625473) value for the next code. That explains the select text that Mikael mentions. But I still have little idea what has led to the code doing this. After briefly trying to manually decode wordcode values, I hacked together a gdb pretty printer for them (attached) which makes it rather easier. Anyway the full wordcode looks like the following. I've manually tried to substitute codes corresponding to strings and indented for some of the skips but am not certain: especially the first string which might be a redirection code. List(type=SYNC|END, skip=0), SubList(type=END, skip=19), Pipe(type=end, line=4), If(type=head, skip=17), If(type=if, skip=16), List(type=SYNC|END|SIMPLE, skip=4), string Cond(-eq, skip=0), string string List(type=SYNC, skip=0), SubList(type=AND, skip=3), Pipe(type=end, line=5), Simple(argc=1), string SubList(type=END, flags=NOT, skip=0), List(type=SYNC|END, skip=0), SubList(type=END, skip=3), Pipe(type=end, line=6), Simple(argc=1), string End Without delving further into this, I'm somewhat unsure as to the meaning of the END types on lists and how start/end matching works along with the stack used in gettext2(). Maybe someone else knows it better? To enable the gdb pretty printer, just dump the file in the current directory and at the gdb prompt, type: python execfile("wordcode.py") To confirm, this worked: info pretty-printer To get line based output it can also be useful to do: set print array on And to watch the parse stage: watch *ecbuf@22 Note that it can't discern the placeholders for strings and I've not tested it exhaustively so there may be errors. There may be nicer ways to handle enabling the pretty-printer; you may have seen this if you've ever enabled to C++ STL pretty printers. Would it make sense to include things like this somewhere in the git repository? It is essentially a duplicate of C code so might bitrot relative to it. Also, I'm not especially fluent in Python, so it could perhaps be better. But it can be useful. I also have a gdb macro for the zle undo stack. Another aside, playing around with bit flags reminded me of a zsh annoyance: printing a negative number in binary gives you a minus sign followed by the positive representation of it rather than the two's complement form. Does it make sense to allow some form of unsigned output besides printf (which doesn't do binary)? And perhaps a Java style >>> operator. Oliver