Version 6.3.18 failing to build from source on i386 architecture
Something changed from version 6.3.17 to version 6.3.18 that is causing the autobuild of the Debian package for praat to fail on the i386 architecture. From the build log, the failure happens for the unit test test_SpeechSynthesizer.praat, with a cryptic message *** stack smashing detected ***: terminated sent after several espeak language files are read. This may have to do with how the FileInMemory data is created in different architectures, but I really have no clue where the problem comes from.
This is "caused" by the Debian packaging building praat with stack protector enabled.
Backtrace:
Core was generated by `/tmp/praat-6.3.18+dfsg/praat_nogui --run runAllTests_batch.praat'.
Program terminated with signal SIGABRT, Aborted.
#0 0xf7fb4559 in __kernel_vsyscall ()
(gdb) bt
#0 0xf7fb4559 in __kernel_vsyscall ()
#1 0xf7889837 in __pthread_kill_implementation (threadid=threadid@entry=4142035712, signo=signo@entry=6, no_tid=no_tid@entry=0)
at ./nptl/pthread_kill.c:43
#2 0xf78898ab in __pthread_kill_internal (signo=6, threadid=4142035712) at ./nptl/pthread_kill.c:78
#3 0xf7839671 in __GI_raise (sig=6) at ../sysdeps/posix/raise.c:26
#4 0xf782227a in __GI_abort () at ./stdlib/abort.c:79
#5 0xf78231b4 in __libc_message (fmt=<optimized out>) at ../sysdeps/posix/libc_fatal.c:150
#6 0xf7932ded in __GI___fortify_fail (msg=0xf79b889b "stack smashing detected") at ./debug/fortify_fail.c:24
#7 0xf7932dc9 in __stack_chk_fail () at ./debug/stack_chk_fail.c:24
#8 0x08e32764 in _fini ()
#9 0x08b5183e in LoadVoice(char const*, int) (vname=<optimized out>, control=<optimized out>) at ./voices.cpp:734
#10 0x08b5251b in espeak_ng_SetVoiceByName(char const*) (name=0x119d68f0 "gu+Demonic") at ./voices.cpp:1318
#11 0x0855f9f3 in SpeechSynthesizer_generateSynthesisData(SpeechSynthesizer, conststring32)
(me=me@entry=0x12b34ca0, text=text@entry=0x12b5c520 U"a e u") at ./SpeechSynthesizer.cpp:726
#12 0x0855fd94 in SpeechSynthesizer_to_Sound(structSpeechSynthesizer*, char32_t const*, autoSomeThing<structTextGrid>*, autoSomeThing<structTable>*) (me=0x12b34ca0, text=0x12b5c520 U"a e u", tg=0x0, events=0x0) at ./SpeechSynthesizer.cpp:803
#13 0x0865c4bf in CONVERT_EACH_TO_ONE__SpeechSynthesizer_to_Sound(UiForm, integer, Stackel, conststring32, Interpreter, conststring32, bool, void*, Editor)
(_sendingForm_=0x128b6ea0, _narg_=0, _args_=0x0, _sendingString_=0x0, interpreter=0x11f33bd0, _invokingButtonTitle_=0x0, _isModified_=false, _buttonClosure_=0x0, _optionalEditor_=0x0) at ./praat_David_init.cpp:6356
#14 0x089b39d1 in UiForm_call(structUiForm*, int, structStackel*, structInterpreter*)
(me=0x128b6ea0, narg=2, args=0xd8fe1e0 <praat_executeCommand(structInterpreter*, char32_t*)::args>, interpreter=0x11f33bd0)
at ./Ui.cpp:2126
#15 0x0865c793 in CONVERT_EACH_TO_ONE__SpeechSynthesizer_to_Sound(UiForm, integer, Stackel, conststring32, Interpreter, conststring32, bool, void*, Editor)
(_sendingForm_=0x0, _narg_=2, _args_=0xd8fe1e0 <praat_executeCommand(structInterpreter*, char32_t*)::args>, _sendingString_=0x0, interpreter=0x11f33bd0, _invokingButtonTitle_=0xffd57074 U"To Sound...", _isModified_=false, _buttonClosure_=0x0, _optionalEditor_=0x0)
at ../sys/Thing.h:297
#16 0x089d4506 in praat_doAction(char32_t const*, int, structStackel*, structInterpreter*)
(title=0xffd57074 U"To Sound...", narg=2, args=0xd8fe1e0 <praat_executeCommand(structInterpreter*, char32_t*)::args>, interpreter=0x11f33bd0) at ./praat_actions.cpp:848
#17 0x089f744b in praat_executeCommand(structInterpreter*, char32_t*) (interpreter=<optimized out>, command=<optimized out>)
at ./praat_script.cpp:452
#18 0x08a15d57 in Interpreter_run(structInterpreter*, char32_t*, bool)
(me=<optimized out>, text=<optimized out>, reuseVariables=<optimized out>) at ./Interpreter.cpp:3328
#19 0x089f6a86 in praat_runScript(char32_t const*, int, structStackel*, structEditor*)
(fileName=0x12b34ca0 U"\x9a28a00\x9a552e0\x12f83d50\x12b5b290\x12b5d440\x12e73fe0\x12b5ce70", narg=0, args=0xf0465024, optionalInterpreterOwningEditor=0x0) at ./Thing.h:297
#20 0x08a2a5fd in do_runScript() () at ./Formula.cpp:4232
#21 0x08a5ef6f in Formula_run(int, int, Formula_Result*) (row=<optimized out>, col=<optimized out>, result=<optimized out>)
at ./Formula.cpp:8352
#22 0x08a0d5aa in Interpreter_voidExpression(structInterpreter*, char32_t const*) (me=0x1224bef0, expression=0x12232d80 U"runScript: file$")
at ./Interpreter.cpp:3457
#23 0x089f8c46 in praat_executeCommand(structInterpreter*, char32_t*) (interpreter=0x1224bef0, command=0x12232d80 U"runScript: file$")
at ./praat_script.cpp:319
#24 0x08a162b1 in Interpreter_run(structInterpreter*, char32_t*, bool)
(me=<optimized out>, text=<optimized out>, reuseVariables=<optimized out>) at ./Interpreter.cpp:3307
#25 0x089f6c39 in praat_executeScriptFromCommandLine(char32_t const*, int, char**)
(fileName=0x119a82d0 U"runAllTests_batch.praat", argc=0, argv=0xffd67270) at ./Thing.h:297
#26 0x089cc1b3 in praat_run() () at ./praat.cpp:2346
#27 0x081261e3 in main(int, char**) (argc=3, argv=0xffd67264) at ./main_Praat.cpp:53
(gdb)
@davidweenink voices.cpp is external/espeak/voices.cpp, this might be due to commit a375c2453e383e248b76acc197302ab0735b0b81 (untested).
Thanks for the diagnosis, @AdrianBunk. Any reason this problem is restricted to i386?
@rlaboiss I wrote everything I know about this, my hope was that someone who knows the Praat code well might understand what happens from the backtrace.
Ok, I patched file external/espeak/create_espeak_ng_FileInMemorySet.cpp and the package
builds successfully on i386. The patch removes the loading of the espeak-ng data file voices/!v/Demonic. I have no idea why the loading of this file was causing the segmentation fault on i386. I will keep this patch for now, until the issue is fixed.
At any rate, the package FTBFS on s390x. Since s390x is one of the official architectures in Debian, this failure will prevent the package from migrating from unstable into testing. @AdrianBunk: any help on debugging this issue will be welcome.
It also fails on ppc64, and the backtrace confirms that it seems to be some big endian issue somewhere (also related to espeak):
Thread 1 "praat_nogui" received signal SIGSEGV, Segmentation fault.
0x000003fffd87ddf0 in fgets () from /lib/s390x-linux-gnu/libc.so.6
(gdb) bt
#0 0x000003fffd87ddf0 in fgets () at /lib/s390x-linux-gnu/libc.so.6
#1 0x00000000018e8822 in fgets (__stream=0x0, __n=1024, __s=0x3ffffffe890 "")
at /usr/include/s390x-linux-gnu/bits/stdio2.h:213
#2 phondata_to_bigendian(FileInMemory, FileInMemory) (me=0xa2b4400, manifest=manifest@entry=0xa33abc0)
at espeak_io.cpp:185
#3 0x00000000018e91de in espeak_ng_data_to_bigendian() () at espeak_io.cpp:347
#4 0x0000000001546962 in espeakdata_praat_init() () at espeakdata_FileInMemory.cpp:58
#5 0x000000000146496a in praat_David_init() () at praat_David_init.cpp:8986
#6 0x0000000001060322 in praat_uvafon_init() () at praat_uvafon_init.cpp:3801
#7 0x000000000101d98c in main(int, char**) (argc=3, argv=0x3fffffff4c8) at main_Praat.cpp:52
(gdb)
Thanks, @AdrianBunk.
Yes, the problem is related to espeak. More specifically, to the way Praat processes the espeak-ng data files (by converting them to FileInMemory). However, the function phondata_to_bigendian, where the segfault happens is a function proper to Praat, that does not come from espeak.
Would it be an acceptable solution to exclude (for now) s390x and ppc64 from the list of architectures on which the praat package should be built?
@rlaboiss I am just a normal Debian developer like you and not at all involved upstream, so my opinion does not have more weight than yours here.
Fiddling with Architecture in Debian packages for bugs is IMHO wrong, I'd wait a few days whether anyone here has a suggestion for a proper fix and it not reportbug ftp.debian.org ask for the removal of the stale s390x binary (which is necessary in any case no matter what Architecture says).
The bug report against ftp.debian.org, requesting the removal of the binary packages for s390x and ppc64, has been filed: Bug#1054573.
I will try to get into this when I have time. It still sounds somewhat mysterious to me especially the !v file not being read. I also will have a look at the big-endian issues
@Adrian I don't get why in the ppc64 backtrace the '... at /usr/include/s390x-linux-gnu/bits/stdio2.h:213' comes from. This fgets should be overwritten by my own version. Is -DDATA_FROM_SOURCECODE_FILES in the makefiles.def ?
Does the problem still exist? We have found and repaired several bugs in eSpeak as well as in how eSpeak is called by Praat, since the last message. Please note that DATA_FROM_SOURCECODE_FILES (mentioned above) should not be #defined when compiling. The script test_SpeechSynthesizer.praat should run as it is, although it generates two "warnings". If the crash persists, I will buy a big-endian computer if I cannot figure it out by looking at the source code.
OK, I have now confirmed the issue for s390x. It crashes in espeak_ng_data_to_bigendian indeed. I will hunt it.
The bug turned out to be in the eSpeak code: they handed an intptr_t to a function that expected an int, thereby throwing away the last four bytes on a 64-bit little-endian machine. As this intptr_t in these cases contained a series of byte-sized characters, and these series tended to be short, the bug surfaced rarely on 64-bit little-endian. On 64-bit big-endian, however, the first four bytes were thrown away instead, and these always contained relevant material (namely phoneme codes). Hence, the bug wasn’t a big-endian bug but a 64-bit bug, but it had visible results especially on big-endian machines.
I saw the stack-smashing with the Demonic voice as well, so I disabled this voice for the moment.
To make Praat run on big-endian s390x, I also had to define the WORDS_BIGENDIAN preprocessor symbol externally on the compile line (i.e. in makefile.defs), in order to have endianness correct in the FLAC, MAD and LAME libraries. Praat now correctly runs test/runAllTests_batch.praat and dwtest/runAllTests_batch.praat. It also has a more or less correctly looking GUI.
Please tell me whether you can now create Praat for s390x on Debian. I have put s390x editions on the Praat site and in the releases list on GitHub.