[Home]

Summary:ASTERISK-22351: Segfault in LIBEDIT_INTERNAL after tgetstr(), when libncurses5-dev isn't installed
Reporter:A. Iglesias (arcanos)Labels:
Date Opened:2013-08-21 04:04:51Date Closed:2013-10-21 14:47:01
Priority:MajorRegression?
Status:Closed/CompleteComponents:Core/BuildSystem Core/General
Versions:1.8.23.0 11.5.0 Frequency of
Occurrence
Constant
Related
Issues:
Environment:HP Proliant DL320e G8 Debian Wheezy (kernel 3.2.0-4-amd64) DAHDI 2.7.0 (no cards installed) Libpri 1.4.14Attachments:( 0) config.h
( 1) config.log
( 2) config.status
( 3) issueA22351_libedit_internal_without_ncurses_dev.patch
Description:New installation in this server. After everything is installed and asterisk started, anytime a try to open an asterisk console with asterisk -vvvvvvvvvr I get a "Segmentation fault" and console doesn't open, but asterisk keeps running. If I stop asterisk and try to start it with asterisk -vvvvvvc, it fails in the same way.

I've been doing some research, and found a guy with the same problem in the past, related whit the value of the TERM system variable. In my case is "xterm", but if I change it for a non existent value ('lalalala' for example) then console starts.

Digging deeper, I've found that the problem is in main/editline/term.c , in line 960 when executing this:

term_alloc(el, t, tgetstr((char *)t->name, &area));

If I change this line with the one executed when TERM has an unknown value...

term_alloc(el, t, NULL);

... and recompile, then console starts.

the problem seems to be in the tgetstr function, because if I add a line just with this...

tgetstr((char *)t->name, &area);

... I get the same error.

I'll try to get core dump stuff, but maybe with this info is enough at the moment to find a solution. I've been trying to find the problem/solution studying the code, but no luck yet.
Comments:By: A. Iglesias (arcanos) 2013-08-21 04:25:23.710-0500

As asterisk doesn't crash, I can't get a core dump file. No file is generated.

Let me know if I can do something to provide more info.

By: Walter Doekes (wdoekes) 2013-08-22 07:00:39.588-0500

You can always get debug info by starting asterisk from gdb.

{noformat}
# gdb asterisk
(gdb) run -vvvvvvvvvvr
...
SEGFAULT

(gdb) bt
..backtrace here..
{noformat}

And what happens if you try this patch?

By: A. Iglesias (arcanos) 2013-08-22 07:23:47.214-0500

Here you have the segfault and backtrace obtained with gdb (thanks for the tip!!):

{noformat}
(gdb) run -vvvvvvvvvvr

Starting program: /usr/sbin/asterisk -vvvvvvvvvvr
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Asterisk 1.8.23.0, Copyright (C) 1999 - 2012 Digium, Inc. and others.
Created by Mark Spencer <markster@digium.com>
Asterisk comes with ABSOLUTELY NO WARRANTY; type 'core show warranty' for details.
This is free software, with components licensed under the GNU General Public
License version 2 and other licenses; you are welcome to redistribute it under
certain conditions. Type 'core show license' for details.
=========================================================================
Connected to Asterisk 1.8.23.0 currently running on asterisk (pid = 3710)

Program received signal SIGSEGV, Segmentation fault.
0x000000000056735c in term_alloc (el=el@entry=0x83a7f0, t=t@entry=0x5c1900, cap=0xffffffffffffcc80 <Address 0xffffffffffffcc80 out of bounds>) at term.c:398
398             if (cap == NULL || *cap == '\0') {


(gdb) bt

#0  0x000000000056735c in term_alloc (el=el@entry=0x83a7f0, t=t@entry=0x5c1900, cap=0xffffffffffffcc80 <Address 0xffffffffffffcc80 out of bounds>)
   at term.c:398
#1  0x0000000000569223 in term_set (el=el@entry=0x83a7f0, term=<optimized out>, term@entry=0x0) at term.c:960
#2  0x000000000056ace7 in term_init (el=0x83a7f0) at term.c:361
#3  el_init (prog=prog@entry=0x583394 "asterisk", fin=0x7ffff77946c0, fout=0x7ffff77947a0, ferr=0x7ffff7794880) at el.c:82
#4  0x000000000043ed93 in ast_el_initialize () at asterisk.c:2730
#5  0x0000000000444260 in ast_remotecontrol (data=<optimized out>) at asterisk.c:2910
#6  0x000000000042337b in main (argc=<optimized out>, argv=0x7fffffffec98) at asterisk.c:3735

(gdb)
{noformat}

I'm going to try the patch...

By: Walter Doekes (wdoekes) 2013-08-22 07:43:20.095-0500

{noformat}
(gdb) up
(gdb) info locals
(gdb) print t
(gdb) print t->name
(gdb) print *t
(gdb) print area
{noformat}

By: A. Iglesias (arcanos) 2013-08-22 07:53:17.021-0500

Before the results, I've see this warning when compiling:

{noformat}
root@asterisk:/usr/src/asterisk-1.8.23.0# make
In file included from editline.c:18:0:
term.c: In function 'term_move_to_line':
term.c:572:6: warning: implicit declaration of function 'tputs' [-Wimplicit-function-declaration]
term.c:572:6: warning: implicit declaration of function 'tgoto' [-Wimplicit-function-declaration]
term.c: In function 'term_set':
term.c:929:2: warning: implicit declaration of function 'tgetent' [-Wimplicit-function-declaration]
term.c:947:3: warning: implicit declaration of function 'tgetflag' [-Wimplicit-function-declaration]
term.c:956:3: warning: implicit declaration of function 'tgetnum' [-Wimplicit-function-declaration]
term.c:960:4: warning: implicit declaration of function 'tgetstr' [-Wimplicit-function-declaration]
term.c:960:4: warning: passing argument 3 of 'term_alloc' makes pointer from integer without a cast [enabled by default]
term.c:391:1: note: expected 'const char *' but argument is of type 'int'
term.c: In function 'term_echotc':
term.c:1458:8: warning: assignment makes pointer from integer without a cast [enabled by default]
{noformat}


An now, here you have the results:

{noformat}
(gdb) up
#1  0x0000000000569223 in term_set (el=el@entry=0x83a7f0, term=<optimized out>, term@entry=0x0) at term.c:960
960                             term_alloc(el, t, tgetstr((char *)t->name, &area));

(gdb) info locals
i = 1
buf = "\033[L\000\000\000\000\000Ö\001", '\000' <repeats 22 times>, "âÖÿÿÿ\177", '\000' <repeats 82 times>, "ÖTH÷ÿ\177\000\000\220Óÿÿÿ\177\000\000\200Óÿÿÿ\177\000\000\005\000\000\000\000\000\000\000ðÔÿÿÿ\177\000\000\220Óÿÿÿ\177\000\000\t8E÷ÿ\177\000\000\000\000\000\000\000\000\000\000\022\000\000\000\000\000\000\000\001", '\000' <repeats 15 times>, "\\9X", '\000' <repeats 29 times>, "ÿÿÿÿ\000\000\000\000\naÞ÷", '\000' <repeats 12 times>, "<~E÷\000\000\000\000(", '\000' <repeats 15 times>, "`Òÿÿÿ\177", '\000' <repeats 18 times>, " FK÷ÿ\177", '\000' <repeats 14 times>...
area = 0x7fffffffcc64 ""
t = <optimized out>
oset = {__val = {0, 0, 140737488343076, 140737488343776, 140737488344016, 140737341914684, 140737488343994, 100, 140737488343080, 0, 140737488343959,
   4148712662, 0, 77309399760, 18, 140737488344200}}
nset = {__val = {134217728, 0 <repeats 15 times>}}
lins = <optimized out>
cols = <optimized out>

(gdb) print t
$1 = <optimized out>

(gdb) print t->name
value has been optimized out

(gdb) print *t
value has been optimized out

(gdb) print area
$2 = 0x7fffffffcc64 ""

(gdb)
{noformat}

By: A. Iglesias (arcanos) 2013-08-22 07:59:21.998-0500

This results are without the patch applied. Also fails with the patch, do you need the results with the patch?

By: Walter Doekes (wdoekes) 2013-08-22 08:07:27.863-0500

Never mind the patch. If it failed, it was useless.

You need to disable optimizations in menuconfig.

Compiler flags => DONT_OPTIMIZE

By: A. Iglesias (arcanos) 2013-08-22 10:24:25.394-0500

I've recompiled with that flag, but getting the same result with gdb. No idea why still optimizing.

By: Walter Doekes (wdoekes) 2013-08-23 01:54:03.013-0500

Ah. The makefiles aren't adapted to disable optimization in editline.

Here:
{noformat}
--- main/editline/Makefile.orig 2013-08-23 08:50:56.471630807 +0200
+++ main/editline/Makefile 2013-08-23 08:50:32.244194710 +0200
@@ -17,7 +17,7 @@
AR = /usr/bin/ar
RANLIB = ranlib
CPPFLAGS =  '-D__RCSID(x)=' '-D__COPYRIGHT(x)=' '-D__RENAME(x)=' '-D_DIAGASSERT(x)=' -I.
-CFLAGS = -pthread -I../..//include -I/usr/include/libxml2 -pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g3  -Wunused -Wdeclaration-after-statement -D_FORTIFY_SOURCE=2 -Wtrampolines -Wundef -Wmissing-format-attribute -Wformat=2 -O6 -march=native  -O
+CFLAGS = -pthread -I../..//include -I/usr/include/libxml2 -pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g3  -Wunused -Wdeclaration-after-statement -D_FORTIFY_SOURCE=2 -Wtrampolines -Wundef -Wmissing-format-attribute -Wformat=2 -march=native
A_CFLAGS =
S_CFLAGS = -fPIC -DPIC
LDFLAGS =    
{noformat}
(remove the -O and -O6)

{noformat}
$ touch main/editline/term.c
$ make -C main/editline
$ make
$ sudo make install
{noformat}

That should get you an unoptimized editline.

By: A. Iglesias (arcanos) 2013-08-23 02:02:18.188-0500

OK!!

{noformat}
Program received signal SIGSEGV, Segmentation fault.
0x0000000000577d7f in term_alloc (el=0x8517f0, t=0x5d8c80, cap=0xffffffffffffca60 <Address 0xffffffffffffca60 out of bounds>) at term.c:398
398             if (cap == NULL || *cap == '\0') {

(gdb) up
#1  0x00000000005796c2 in term_set (el=0x8517f0, term=0x7fffffffeea1 "xterm") at term.c:960
960                             term_alloc(el, t, tgetstr((char *)t->name, &area));

(gdb) info locals
i = 1
buf = "\033[L\000ÿ\177\000\000\022", '\000' <repeats 15 times>, "\220Êÿÿÿ\177\000\000\"\226Y\000\000\000\000\000s\000\000\000\000\000\000\000¨Îÿÿÿ\177\000\000\000\000\000\000\000\000\000\000\nÒÿÿ", '\000' <repeats 68 times>, " Ëÿÿÿ\177\000\000ø\025\205", '\000' <repeats 13 times>, "ÿÿÿÿÿÿÿÿ\000\000\000\000ÿ\177\000\000\207Íÿÿ\000\000\000\000\a\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000ÿ\177\000\000\001\200­û", '\000' <repeats 12 times>, "ø\025\205", '\000' <repeats 13 times>, "ÿÿÿÿ\000\000\000\000\002\000\000\000\000\000\000\000°Îÿÿÿ\177\000\000<~E÷ÿ\177\000\000"...
area = 0x7fffffffca64 "ÿ\177"
t = 0x5d8c80
oset = {__val = {0, 0, 0, 0, 0, 140737342293606, 0, 0, 140737488341733, 140733193388032, 140737488342912, 2, 140737488343264, 140737488343248, 5,
   140737488343616}}
nset = {__val = {134217728, 0 <repeats 15 times>}}
lins = 32767
cols = -12320

(gdb) print t
$1 = (const struct termcapstr *) 0x5d8c80

(gdb) print t->name
$2 = 0x5d8964 "al"

(gdb) print *t
$3 = {name = 0x5d8964 "al", long_name = 0x5d8967 "add new blank line"}

(gdb) print area
$4 = 0x7fffffffca64 "ÿ\177"

(gdb)
{noformat}

By: Walter Doekes (wdoekes) 2013-08-23 02:33:51.461-0500

What about this?

By: Walter Doekes (wdoekes) 2013-08-23 02:38:36.942-0500

Or this.

By: Walter Doekes (wdoekes) 2013-08-23 02:41:00.930-0500

Wait a minute. Is &buf equal to cap?

By: A. Iglesias (arcanos) 2013-08-23 02:54:23.737-0500

Both patches fails. Here you have the results with the second patch:

{noformat}
(gdb) up
#1  0x0000000000579629 in term_set (el=0x8517f0, term=0x7fffffffeea1 "xterm") at term.c:961
961                             term_alloc(el, t, tgetstr((char *)t->name, &area));

(gdb) info locals
i = 1
buf = "\220Ø\200\000\000\000\000\000ê1N\000\000\000\000\000\000\000\000\000\030\004\000\000+×[\000\000\000\000\000\220Ø\200\000\000\000\000\000Àã[\000\000\000\000\000\200¥ÿÿ\030\004\000\000´Õ[", '\000' <repeats 21 times>, "\200¥ÿÿÿ\177\000\000ÿ_N", '\000' <repeats 37 times>, "  == Par7YN\000\000\000\000\000tc/asterisk/aste  == Found\n", '\000' <repeats 21 times>, "\020\000\000\000\000\000\000\000@\023\205", '\000' <repeats 6573 times>, "ÖTH÷ÿ\177\000\000\220£ÿÿÿ\177\000\000\200£ÿÿÿ\177\000\000\f\000\000\000\000\000\000\000(¥ÿÿÿ"...
area = 0x7fffffffaa64 "ected to Asterisk 1.8.23.0 currently running on asterisk (pid = 4521)\n"
t = 0x5d8c00
oset = {__val = {0, 0, 140737488323216, 4334848, 140737488350320, 140737351977557, 8444560, 8444560, 6022080, 980, 8444560, 6020814, 7291089341863848307,
   140737354129864, 238, 5124586}}
nset = {__val = {134217728, 0 <repeats 15 times>}}
lins = 0
cols = 0

(gdb) print t
$1 = (const struct termcapstr *) 0x5d8c00

(gdb) print t->name
$2 = 0x5d88e4 "al"

(gdb) print *t
$3 = {name = 0x5d88e4 "al", long_name = 0x5d88e7 "add new blank line"}

(gdb) print area
$4 = 0x7fffffffaa64 "ected to Asterisk 1.8.23.0 currently running on asterisk (pid = 4521)\n"
{noformat}

By: Walter Doekes (wdoekes) 2013-08-23 03:03:04.597-0500

And what were cap and &buf ?

And what what is the output of: make -C main/editline
Does anything change if you remove -D_FORTIFY_SOURCE=2 ?

By: A. Iglesias (arcanos) 2013-08-23 03:26:18.488-0500

{noformat}
(gdb) print buf
$5 = "\220Ø\200\000\000\000\000\000ê1N\000\000\000\000\000\000\000\000\000\030\004\000\000+×[\000\000\000\000\000\220Ø\200\000\000\000\000\000Àã[\000\000\000\000\000\200¥ÿÿ\030\004\000\000´Õ[", '\000' <repeats 21 times>, "\200¥ÿÿÿ\177\000\000ÿ_N", '\000' <repeats 37 times>, "  == Par7YN\000\000\000\000\000tc/asterisk/aste  == Found\n", '\000' <repeats 21 times>, "\020\000\000\000\000\000\000\000@\023\205", '\000' <repeats 6573 times>, "ÖTH÷ÿ\177\000\000\220£ÿÿÿ\177\000\000\200£ÿÿÿ\177\000\000\f\000\000\000\000\000\000\000(¥ÿÿÿ"...

(gdb) print &buf
$6 = (char (*)[20480]) 0x7fffffff8260
{noformat}

cap is not created, because is one of the term_alloc arguments, and I think term_alloc is not executed because the segfault is caused by the tgetstr call.


{noformat}
root@asterisk:/usr/src/asterisk-1.8.23.0# make -C main/editline

make: se ingresa al directorio `/usr/src/asterisk-1.8.23.0/main/editline'
gcc -c -fPIC -DPIC -pthread -I../..//include -I/usr/include/libxml2 -pipe -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -g3 -march=native '-D__RCSID(x)=' '-D__COPYRIGHT(x)=' '-D__RENAME(x)=' '-D_DIAGASSERT(x)=' -I. editline.c -o editline.o_s
In file included from editline.c:18:0:
term.c: In function 'term_move_to_line':
term.c:572:6: warning: implicit declaration of function 'tputs' [-Wimplicit-function-declaration]
term.c:572:6: warning: implicit declaration of function 'tgoto' [-Wimplicit-function-declaration]
term.c: In function 'term_set':
term.c:930:2: warning: implicit declaration of function 'tgetent' [-Wimplicit-function-declaration]
term.c:948:3: warning: implicit declaration of function 'tgetflag' [-Wimplicit-function-declaration]
term.c:957:3: warning: implicit declaration of function 'tgetnum' [-Wimplicit-function-declaration]
term.c:961:4: warning: implicit declaration of function 'tgetstr' [-Wimplicit-function-declaration]
term.c:961:4: warning: passing argument 3 of 'term_alloc' makes pointer from integer without a cast [enabled by default]
term.c:391:1: note: expected 'const char *' but argument is of type 'int'
term.c: In function 'term_echotc':
term.c:1459:8: warning: assignment makes pointer from integer without a cast [enabled by default]
gcc -shared -o libedit.so.2 editline.o_s np/fgetln.o_s np/vis.o_s np/unvis.o_s np/strlcpy.o_s np/strlcat.o_s history.o_s tokenizer.o_s readline.o_s -ltermcap

make: se sale del directorio `/usr/src/asterisk-1.8.23.0/main/editline'
{noformat}

¿¿ Where is -D_FORTIFY_SOURCE=2 ??


By: Walter Doekes (wdoekes) 2013-08-23 04:37:27.429-0500

{quote}
0x0000000000577d7f in term_alloc (el=0x8517f0, t=0x5d8c80, cap=0xffffffffffffca60 <Address 0xffffffffffffca60 out of bounds>) at term.c:398
{quote}

There have have the address of cap. If that is in ( &buf <= cap < &buf+TC_BUFSIZE ) then there shouldn't be a problem. If it isn't then your tgetstr is behaving really oddly.

{quote}
¿¿ Where is -D_FORTIFY_SOURCE=2 ??
{quote}
Apparently you don't have that. In that case you can't remove it either :)

The only thing I can think of now is to clear buf at the start. That might help.

{noformat}
--- main/editline/term.c (revision 397415)
+++ main/editline/term.c (working copy)
@@ -902,7 +902,7 @@
term_set(EditLine *el, const char *term)
{
int i;
- char buf[TC_BUFSIZE];
+ char buf[TC_BUFSIZE] = {0,};
char *area;
const struct termcapstr *t;
sigset_t oset, nset;
{noformat}

By: A. Iglesias (arcanos) 2013-08-23 04:51:51.311-0500

Same failure cleaning buf...

in the line you mention, cap is the result of calling tgetstr (the call the originate the failure). It's clear that the segfault is originated by this:

tgetstr((char *)t->name, &area);

I mean, term_alloc is never executed because tgetstr fails before. By the way, where is tgetstr function? I've tried to find it to see what it does, but I've been uncapable.

By: Walter Doekes (wdoekes) 2013-08-23 05:23:57.107-0500

{quote}
in the line you mention, cap is the result of calling tgetstr (the call the originate the failure). It's clear that the segfault is originated by this:
{quote}

Well, no.

The backtrace you pasted shows that the segfault happens upon touching the *result* of the tgetstr() call. This: {{0xffffffffffffca60 <Address 0xffffffffffffca60 out of bounds>}}
It's not the call itself that segfaults.

If {{( &buf <= cap < &buf+TC_BUFSIZE )}} then there shouldn't be a problem, since cap is in a valid range.

{quote}
By the way, where is tgetstr function?
{quote}
It fetches the "right" console_code to perform a specific non-printing action on the tty:
{noformat}
{ "al", "add new blank line" },
{noformat}

Over here, it returns:
{noformat}
"\x1b[L" (try: printf '\x1b[L')
{noformat}
Or:
{noformat}
{ "cl", "clear screen" },
{noformat}
Returns:
{noformat}
"\x1b[H\x1b[2J" (try: printf '\x1b[H\x1b[2J')
{noformat}

By: A. Iglesias (arcanos) 2013-08-23 05:37:33.337-0500

| The backtrace you pasted shows that the segfault happens upon touching the result of the tgetstr() call. | This: 0xffffffffffffca60 <Address 0xffffffffffffca60 out of bounds>
| It's not the call itself that segfaults.

Ummm, I don't think so... If I put this line in the code...

tgetstr((char *)t->name, &area);

... the it fails here and never reaches de term_alloc function (that's what make me think the segfault is originated by the tgetstr call).


Program received signal SIGSEGV, Segmentation fault.
0x0000000000569216 in term_set (el=el@entry=0x83a7f0, term=<optimized out>, term@entry=0x0) at term.c:960
960                     tgetstr((char *)t->name, &area);


By: Walter Doekes (wdoekes) 2013-08-23 05:53:01.006-0500

You're now looking at a segfault in term_set, not in tgetstr. I'm betting 't' is uninitialized and points to NULL or garbage. That would be your doing.

(And it's optimized again.)
(And you're still not answering my question about cap.)

By: A. Iglesias (arcanos) 2013-08-23 07:02:18.029-0500

Optimization was activated again because I was doing some tests. Removed again...

You're right, I was using t outside the for itineration where it's declared. Sorry if I'm not to fast, but it's been a long time since my c programming, and I'm trying to remember while I'm studyng the code, so sometimes is not clear to me what you're asking for.

About the cap...

{noformat}
(gdb) print cap
$1 = 0xffffffffffffad20 <Address 0xffffffffffffad20 out of bounds>

(gdb) print &cap
$2 = (const char **) 0x7fffffff3398

(gdb) up
#1  0x0000000000571089 in term_set (el=0x8417f0, term=0x7fffffffeea1 "xterm") at term.c:963
963                             term_alloc(el, t, tgetstr((char *)t->name, &area));

(gdb) print buf
$3 = '\000' <repeats 10240 times>, "\033[L", '\000' <repeats 10236 times>

(gdb) print &buf
$4 = (char (*)[20480]) 0x7fffffff8520
{noformat}

So it seems cap (0x7fffffff3398) < buf (0x7fffffff8520)  ... right?

By: Walter Doekes (wdoekes) 2013-08-23 07:34:45.260-0500

Not &cap but cap.

And cap is 0xffffffffffffad20 while it should land somewhere in buf (which is at 0x7fffffff8520 and upwards).

That's a problem. I missed the first 'f' in your bug report.

Let's see what we have here.

(0xffffffffffffad20 & 0x7fffffffffffffff) - 0x7fffffff8520 = that's exactly (TC_BUFSIZE / 2) of {{issueA22351_larger_buf_and_offset.patch}}.

According to this bug report [1] it has (A) something to do with the compiler version or (B) is fixable by passing a non-portable NULL to tgetstr.

In your case however, the problem should be fixed by:
- casting the return value the right way
- dropping the first bit
- ignoring the return value and using buf instead

[1] http://bugs.mysql.com/bug.php?id=45562

By: Walter Doekes (wdoekes) 2013-08-23 07:42:12.739-0500

And that's probably just because of the missing declaration...

Put this at the top of the file (below #include "el.h")

{noformat}
(char *) tgetstr (const char *, char **);
{noformat}

You should now get one less compiler warning.

That should probably be wrapped inside some {{#if !defined(HAVE_TERMCAP_H) and !defined(...}} but I'd like to know if it fixes things first.

By: A. Iglesias (arcanos) 2013-08-23 07:52:05.338-0500

With this...

(char *) tgetstr (const char *, char **);

... it doesn't compile...

{noformat}
root@asterisk:/usr/src/asterisk-1.8.23.0# make

CC="cc" CXX="" LD="" AR="" RANLIB="" CFLAGS="" make -C menuselect CONFIGURE_SILENT="--silent" makeopts
make[1]: se ingresa al directorio `/usr/src/asterisk-1.8.23.0/menuselect'
make[1]: `makeopts' está actualizado.
make[1]: se sale del directorio `/usr/src/asterisk-1.8.23.0/menuselect'
In file included from editline.c:18:0:
term.c:81:2: error: expected identifier or '(' before 'char'
term.c: In function 'term_move_to_line':
term.c:572:6: warning: implicit declaration of function 'tputs' [-Wimplicit-function-declaration]
term.c:572:6: warning: implicit declaration of function 'tgoto' [-Wimplicit-function-declaration]
term.c: In function 'term_set':
term.c:929:2: warning: implicit declaration of function 'tgetent' [-Wimplicit-function-declaration]
term.c:947:3: warning: implicit declaration of function 'tgetflag' [-Wimplicit-function-declaration]
term.c:956:3: warning: implicit declaration of function 'tgetnum' [-Wimplicit-function-declaration]
term.c:960:4: warning: implicit declaration of function 'tgetstr' [-Wimplicit-function-declaration]
term.c:960:4: warning: passing argument 3 of 'term_alloc' makes pointer from integer without a cast [enabled by default]
term.c:391:1: note: expected 'const char *' but argument is of type 'int'
term.c: In function 'term_echotc':
term.c:1458:8: warning: assignment makes pointer from integer without a cast [enabled by default]
make[2]: *** [editline.o_a] Error 1
make[1]: *** [editline/libedit.a] Error 2
make: *** [main] Error 2
{noformat}

The solution that appears in the Mysql bug report of passing the NULL value to tgetstr works.

By: Walter Doekes (wdoekes) 2013-08-23 08:03:42.323-0500

Sorry, should've been:
{noformat}
char * tgetstr (const char *, char **);
{noformat}

And yes, the NULL passing probably works (on certain systems), but then you have to remember to free the area too.

By: A. Iglesias (arcanos) 2013-08-23 13:03:20.521-0500

Works!!!

And as you said, this related compiler warnings are gone:

term.c:959:4: warning: implicit declaration of function 'tgetstr' [-Wimplicit-function-declaration]
term.c:959:4: warning: passing argument 3 of 'term_alloc' makes pointer from integer without a cast [enabled by default]
term.c:391:1: note: expected 'const char *' but argument is of type 'int'
term.c: In function 'term_echotc':
term.c:1457:8: warning: assignment makes pointer from integer without a cast [enabled by default]

By: Walter Doekes (wdoekes) 2013-08-26 02:01:50.324-0500

From the directory {{main/editline}}: please upload {{config.h}}, {{config.status}}, {{config.log}}.

You're expected to have either term+curses or termcap. You seem to not have term, but the build process still continued. We'd need to reorder the #if's in term.c to include those declarations that you're missing.

By: A. Iglesias (arcanos) 2013-08-26 07:03:45.600-0500

Files attached.

By: A. Iglesias (arcanos) 2013-08-26 07:54:50.245-0500

Hi Walter

I think I've found the problem in my system. Before compiling asterisk, I always run the install_prereq script to be sure all dependencies are installed in the system. Considering what you've said, I've been searching the ncurses related packages installed in the system, and I've seen that libncurses5 and libncursesw5 are installed, but libncurses5-dev and libncursesw5-dev no. So I've installed both packages, removed the function declaration we put, then...

make clean
./configure
make
make install

... and no compilation warnings and now it works!!!

So, considering this, apart from my mistake of not install this dev packages, I think there are two things that can avoid this situation:

- Include libncurses5-dev and libncursesw5-dev in the install-prereq script verification. I've seen now it checks libncurses-dev, but it seems this is not working.

- For what you said, if no term+ncurses or termcap are present, the compiler should have given error, is it correct? I think that's what you're currently looking at.

Let me know if you need me to do more tests or give you more info.

By: Walter Doekes (wdoekes) 2013-08-26 08:20:07.439-0500

Ok. Then this should be right for you.

By: Walter Doekes (wdoekes) 2013-08-26 08:22:38.966-0500

I reproduced it myself in the mean time.

On my ubuntu, it was a matter of removing libncurses5-dev.

The termcap lib itself was still available, but the declarations weren't right.
{noformat}
libtinfo-dev: /usr/lib/x86_64-linux-gnu/libtermcap.so
{noformat}

We could #error if there was no TERMCAP and no NCURSES and no CURSES. But I think allowing compilation trumps complaining.

By: A. Iglesias (arcanos) 2013-08-27 02:10:49.013-0500

Yes, you're probably right about compiling error. In case of putting something, maybe should be just a warning, something like "check if libncurses-dev is installed" or similar. Anyway, your term.c patch should avoid the segfault, although I don't know if libncurses-dev is necessary in other parts of asterisk.

What I still don't understand is why the install-prereq script doesn't install this package. Yesterday I checked other machine installed with Wheezy in the same way, and the package wasn't installed either. I ran the script again, and it returned that everything is OK (nothing installed), while it should have installed this package. In fact, if you remove the linbcurses5-dev package and run the script, nothing happens.

Next time I install a new machine, I'll pay attention at the script execution in a new system, to see if it install everything or return some kind of warning.

I'm not sure what's the best option for this case. Honestly, I think is better to find a way that assure the package libncurses5-dev is installed, to avoid future problems.