SIGSEGV error in some lua/c++ code - c++

The following code end in a SIGSEGV error:
extern "C" {
#include "lua/lua.h"
#include "lua/lualib.h"
#include "lua/lauxlib.h"
}
int main( int argc, char *argv[] )
{
lua_State *L;
luaL_openlibs(L);
lua_close(L);
return 0;
}
Gdb gives me the following:
(gdb) run
Starting program: d:\Dropbox\cpp\engine\bin\main.exe
[New Thread 7008.0x1df8]
Program received signal SIGSEGV, Segmentation fault.
0x6d781f30 in lua_pushcclosure () from d:\Dropbox\cpp\engine\bin\lua52.dll
(gdb) where
#0 0x6d781f30 in lua_pushcclosure () from d:\Dropbox\cpp\engine\bin\lua52.dll
#1 0x6d79329e in luaL_requiref () from d:\Dropbox\cpp\engine\bin\lua52.dll
#2 0x6d79bdee in luaL_openlibs () from d:\Dropbox\cpp\engine\bin\lua52.dll
#3 0x004013a6 in main (argc=1, argv=0x702fc8) at main.cpp:10
(gdb)

You have to do create a new lua state before opening the lib (luaL_openlibs(L);), like this:
L = luaL_newstate();
You get the segmentation fault because you have an unitialized pointer, dereferencing it (which is what the lib does) is undefined behavior.

Related

Receiving RTCP issues within oRTP library

I am currently getting a segfault when trying to receive RTCP in RECVONLY sessions in oRTP. RTCP works fine when receiving in a SENDRECV session but won't work in RECVONLY sessions.
This is my code. The segfault comes from the function on line 42: err=rtp_session_recv_with_ts(session,buffer,160,ts,&have_more);
This is in the while loop that receives the file.
However, this only occurs on line 32
rtp_session_enable_rtcp(session,TRUE); is set to TRUE.
If I disable RTCP by setting it to FALSE, then the RECVONLY session works.
#include <ortp/ortp.h>
#include <bctoolbox/vfs.h>
#include <signal.h>
#include <stdlib.h>
int cond=1;
void stop_handler(int signum)
{
cond=0;
}
int main(int argc, char*argv[])
{
RtpSession *session;
unsigned char buffer[160];
int err;
uint32_t ts=0;
int stream_received=0;
FILE *outfile;
int local_port;
int have_more;
int i;
local_port=atoi(argv[2]);
outfile=fopen(argv[1],"wb");
//initialization of the session
ortp_init();
ortp_scheduler_init();
ortp_set_log_level_mask(NULL, ORTP_DEBUG|ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR);
signal(SIGINT,stop_handler);
session=rtp_session_new(RTP_SESSION_RECVONLY);
rtp_session_enable_rtcp(session,TRUE);
rtp_session_set_scheduling_mode(session,1);
rtp_session_set_blocking_mode(session,1);
rtp_session_set_local_addr(session,"0.0.0.0",local_port,local_port+1);
rtp_session_set_payload_type(session,0);
//receiving of incoming file
while(cond)
{
have_more=1;
while (have_more){
err=rtp_session_recv_with_ts(session,buffer,160,ts,&have_more);
if (err>0) stream_received=1;
/* this is to avoid to write to disk some silence before the first RTP packet is returned*/
if ((stream_received) && (err>0)) {
size_t ret = fwrite(buffer,1,err,outfile);
}
}
ts+=160;
}
rtp_session_destroy(session);
ortp_exit();
ortp_global_stats_display();
return 0;
}
Using gdb to debug, I get this backtrace of the segfault.
Thread 1 "err" received signal SIGSEGV, Segmentation fault.
0x00007ffff7bd0a53 in concatb (mp=mp#entry=0x606ec0, newm=newm#entry=0x0)
at /usr/src/debug/ortp-1.0.1-18/src/str_utils.c:337
337 while(newm->b_cont!=NULL) newm=newm->b_cont;
(gdb) bt
#0 0x00007ffff7bd0a53 in concatb (mp=mp#entry=0x606ec0, newm=newm#entry=0x0)
at /usr/src/debug/ortp-1.0.1-18/src/str_utils.c:337
#1 0x00007ffff7bc4ada in append_sdes (full=1 '\001', m=0x606ec0, session=0x602750)
at /usr/src/debug/ortp-1.0.1-18/src/rtcp.c:397
#2 rtp_session_create_and_send_rtcp_packet (session=session#entry=0x602750, full=full#entry=1 '\001')
at /usr/src/debug/ortp-1.0.1-18/src/rtcp.c:460
#3 0x00007ffff7bc4d3e in rtp_session_send_regular_rtcp_packet_and_reschedule (
session=session#entry=0x602750, tc=607522024) at /usr/src/debug/ortp-1.0.1-18/src/rtcp.c:569
#4 0x00007ffff7bc4ebd in rtp_session_run_rtcp_send_scheduler (session=session#entry=0x602750)
at /usr/src/debug/ortp-1.0.1-18/src/rtcp.c:604
#5 0x00007ffff7bc5085 in rtp_session_rtcp_process_recv (session=session#entry=0x602750)
at /usr/src/debug/ortp-1.0.1-18/src/rtcp.c:620
#6 0x00007ffff7bca985 in rtp_session_recvm_with_ts (session=session#entry=0x602750,
user_ts=user_ts#entry=30880) at /usr/src/debug/ortp-1.0.1-18/src/rtpsession.c:1287
#7 0x00007ffff7bcab24 in rtp_session_recv_with_ts (session=0x602750,
buffer=0x7fffffffdf90 "\226ˢT\277\274\350/։c\276e\257\377\377\377\377\376\177\357\377\377\377\277\372\377\377\377\377\377\377\377\356?r\337\301h\225s`\020HvHfJv\312\062\364\332\333\036\364\332fͽL\002\220d\"\206\354b\006\003\060\241cHV21\243Z!\v\r\202\271\214x0\004Pc$\306<\306\006;\270i\352\206l\030`\244#\244\303\071\253\070\"T\356\002\017\004\"8e\377\062\260\225\376\245bG\310\320H", len=160, ts=30880, have_more=0x7fffffffdf8c)
at /usr/src/debug/ortp-1.0.1-18/src/rtpsession.c:1364
#8 0x0000000000400d15 in main ()
From the backtrace, it look as if there is an issue in the library file str_utils.c, but I'm not sure if I'm just forgetting initialize something when setting up a RECVONLY session.
Overall, it looks as though the receiver function on line 42 does not work with RTCP in a RECVONLY session. There are no issues if RTCP is disabled.

Backtrace inside Signal Handler

I'm trying to following the code from this post to have signal handlers print a backtrace on errors such as floating point and segmentation faults. I'm using seg fault signals as a starting point. Here is the code:
#include <cstdlib> //for exit()
#include <signal.h> //signal handling
#include <execinfo.h> //backtrace, backtrace_symbols and backtrace_fd
#include <iostream>
#include <string.h>
#include <stdio.h>
#define TRACE_MSG fprintf(stderr, "TRACE at: %s() [%s:%d]\n", \
__FUNCTION__, __FILE__, __LINE__)
void show_stackframe()
{
void *trace[1024];
char **messages = (char **) NULL;
int i, trace_size = 0;
TRACE_MSG;
trace_size = backtrace(trace, 1024); // segfault here???
// More code here to print backtrace, but not needed at the moment..
TRACE_MSG;
}
void sigSegvHandler( int signum, siginfo_t* info, void* arg )
{
TRACE_MSG;
show_stackframe();
return;
}
double func_b()
{
show_stackframe(); // Show that backtrace works without being
// called inside sighandler.
TRACE_MSG;
int int_a[5];
int_a[0] = 4;
int_a[11] = 10; // cause a segfault on purpose to see
// how the signal handling performs.
return 1.1;
}
int main()
{
// Examine and change the seg fault signal
struct sigaction segvAction; // File: /usr/include/bits/sigaction.h
// Initialize segvAction struct to all zeros for initialiation
memset( &segvAction, 0, sizeof( segvAction ) );
segvAction.sa_sigaction = sigSegvHandler;
segvAction.sa_flags = SA_SIGINFO; //Invoke signal catching function with 3 arguments instead of 1
// Set the action for the SIGSEGV signal
sigaction( SIGSEGV, &segvAction, NULL );
func_b(); // Produce a SIGSEGV error
}
I am compiling using:
g++ -rdynamic testprogram.cpp -o testprogram
I receive the following output from the program:
TRACE at: show_stackframe() [stackoverflow.cpp:15]
TRACE at: show_stackframe() [stackoverflow.cpp:17]
TRACE at: func_b() [stackoverflow.cpp:33]
TRACE at: sigSegvHandler() [stackoverflow.cpp:22]
TRACE at: show_stackframe() [stackoverflow.cpp:15]
Segmentation fault
My question is why does show_stackframe() cause a segmentation fault inside of sigaction but works fine when not inside of the sigaction handler? I obviously seem to be setting up the signal handler/action incorrect but I haven't been able to find it all day. GDB doesn't seem to be any help in this case.
As stated here, the backtrace function is AS-Unsafe, which means it is unsafe to call from an asynchronous signal handler. Doing so invokes undefined behavior.

Thread name not shown in info thread command when using gdb 7.7

In some of the answers to related questions I could see that gdb 7.3 should support displaying thread names atleast with 'info threads' command .
But I am not even getting that luxury. please help me to understand what I am doing wrong.
My sample code used for testing:
#include <stdio.h>
#include <pthread.h>
#include <sys/prctl.h>
static pthread_t ta, tb;
void *
fx (void *param)
{
int i = 0;
prctl (PR_SET_NAME, "Mythread1", 0, 0, 0);
while (i < 1000)
{
i++;
printf ("T1%d ", i);
}
}
void *
fy (void *param)
{
int i = 0;
prctl (PR_SET_NAME, "Mythread2", 0, 0, 0);
while (i < 100)
{
i++;
printf ("T2%d ", i);
}
sleep (10);
/* generating segmentation fault */
int *p;
p = NULL;
printf ("%d\n", *p);
}
int
main ()
{
pthread_create (&ta, NULL, fx, 0);
pthread_create (&tb, NULL, fy, 0);
void *retval;
pthread_join (ta, &retval);
pthread_join (tb, &retval);
return 0;
}
Output( using core dump generated by segmentation fault)
(gdb) core-file core.14001
[New LWP 14003]
[New LWP 14001]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/libthread_db.so.1".
Core was generated by `./thread_Ex'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x08048614 in fy (param=0x0) at thread_Ex.c:30
30 printf("%d\n",*p);
(gdb) info threads
Id Target Id Frame
2 Thread 0xb77d76c0 (LWP 14001) 0x00b95424 in __kernel_vsyscall ()
* 1 Thread 0xb6dd5b70 (LWP 14003) 0x08048614 in fy (param=0x0) at thread_Ex.c:30
(gdb) bt
#0 0x08048614 in fy (param=0x0) at thread_Ex.c:30
#1 0x006919e9 in start_thread () from /lib/libpthread.so.0
#2 0x005d3f3e in clone () from /lib/libc.so.6
(gdb) thread apply all bt
Thread 2 (Thread 0xb77d76c0 (LWP 14001)):
#0 0x00b95424 in __kernel_vsyscall ()
#1 0x006920ad in pthread_join () from /lib/libpthread.so.0
#2 0x080486a4 in main () at thread_Ex.c:50
Thread 1 (Thread 0xb6dd5b70 (LWP 14003)):
#0 0x08048614 in fy (param=0x0) at thread_Ex.c:30
#1 0x006919e9 in start_thread () from /lib/libpthread.so.0
#2 0x005d3f3e in clone () from /lib/libc.so.6
(gdb) q
As you can see I cant see any thread names that I have set. what could be wrong?
Note:
I am using gdb version 7.7 (Downloaded and compiled using no special options)
commands used to compile & install gdb : ./configure && make && make install
As far as I am aware, thread names are not present in the core dump.
If they are available somehow, please file a gdb bug.
I get thread name displayed on CentOS6.5, but not displayed on CentOS6.4 .

Is it possible to automaticly restart program in GDB after exception (segfault) error?

How I can run a program in C++ with GDB so that in case of error exception (segfaults) restarted the program (I want that GDB automatically use "run" command), and at the same time any errors logged to a file (command "where").
Is it at possible?
Let me show you an example that restarts a program for 3 times in case it crashes. I use a python script to handle SIGSEGV (https://sourceware.org/gdb/onlinedocs/gdb/Events-In-Python.html).
First, this is an example of a GDB session:
>gdb -q -x restart.py ./a.out
Reading symbols from /home/a.out...done.
process id: 1700
Program received signal SIGSEGV, Segmentation fault.
0x000000000040060e in c () at main2.cpp:9
9 *ptr = *ptr +1;
#0 0x000000000040060e in c () at main2.cpp:9
#1 0x000000000040062a in main () at main2.cpp:15
process id: 1704
Program received signal SIGSEGV, Segmentation fault.
0x000000000040060e in c () at main2.cpp:9
9 *ptr = *ptr +1;
#0 0x000000000040060e in c () at main2.cpp:9
#1 0x000000000040062a in main () at main2.cpp:15
process id: 1705
Program received signal SIGSEGV, Segmentation fault.
0x000000000040060e in c () at main2.cpp:9
9 *ptr = *ptr +1;
#0 0x000000000040060e in c () at main2.cpp:9
#1 0x000000000040062a in main () at main2.cpp:15
process id: 1706
Program received signal SIGSEGV, Segmentation fault.
0x000000000040060e in c () at main2.cpp:9
9 *ptr = *ptr +1;
#0 0x000000000040060e in c () at main2.cpp:9
#1 0x000000000040062a in main () at main2.cpp:15
(gdb)
For each crash a file with a name crash.file.PID is created. This is an example of a file:
>more crash.file.1860
#0 0x000000000040060e in c () at main2.cpp:9
#1 0x000000000040062a in main () at main2.cpp:15
This is a C++ program:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int c()
{
printf("process id: %d\n", getpid());
int *ptr =0;
*ptr = *ptr +1;
return *ptr;
}
int main()
{
c();
return 0;
}
This is a python script:
>cat restart.py
#!gdb
import sys
import gdb
import os
number_restarts = 3
def on_stop(sig):
global number_restarts
if isinstance(sig, gdb.SignalEvent) and sig.stop_signal == "SIGSEGV":
crash_file = "crash.file." + str( gdb.selected_inferior().pid)
gdb.execute("set logging file " + crash_file)
gdb.execute("set logging on")
gdb.execute("where")
gdb.execute("set logging off")
if (number_restarts > 0):
number_restarts -= 1
gdb.execute("set confirm off")
gdb.execute("kill")
gdb.execute("run")
gdb.events.stop.connect (on_stop)
gdb.execute("set pagination off")
gdb.execute("run")

gdb outputs std error

gdb is giving me the following
Program received signal SIGABRT, Aborted.
0x000001efa0f31eea in kill () at <stdin>:2
2 <stdin>: No such file or directory.
in <stdin>
(gdb) where
#0 0x000001efa0f31eea in kill () at <stdin>:2
#1 0x000001efa0f986ca in abort () at /usr/src/lib/libc/stdlib/abort.c:70
#2 0x000001efa8473e71 in __gnu_cxx::__verbose_terminate_handler () at /usr/obj/gcc-4.7.2/gcc-4.7.2/libstdc++-v3/libsupc++/vterminate.cc:50
#3 0x000001efa8471ba8 in __cxxabiv1::__terminate (handler=Unhandled dwarf expression opcode 0xf3
) at /usr/obj/gcc-4.7.2/gcc-4.7.2/libstdc++-v3/libsupc++/eh_terminate.cc:40
#4 0x000001efa8471bf3 in std::terminate () at /usr/obj/gcc-4.7.2/gcc-4.7.2/libstdc++-v3/libsupc++/eh_terminate.cc:50
Die: DW_TAG_unspecified_type (abbrev = 23, offset = 133635)
has children: FALSE
attributes:
DW_AT_name (DW_FORM_strp) string: "decltype(nullptr)"
Dwarf Error: Cannot find type of die [in module /usr/local/lib/libestdc++.so.15.0]
I am working on openbsd 5.3 has anyone come across this issue?
#include <iostream>
int main (void) {
try {
throw 10;
}catch (...) {
std::cout<<"thrown"<<std::endl;
}
return 0;
}
This is enough to cause the problem