Hi, everyone!
I thought I posted the code first, it's better. This is the code of the program I've worked with :

#include "liveMedia.hh"
#include "BasicUsageEnvironment.hh"
#include <stdio.h>

UsageEnvironment* env;
Boolean reuseFirstSource = False;
Boolean iFramesOnly = False;

static void announceStream(RTSPServer* rtspServer, ServerMediaSession* sms,
			   char const* streamName, char* inputFileName); // fwd

char* getFileName(int choice);
char* getFileName(int choice)
{
	char* inputFile = "";
	switch(choice){
		case 1: inputFile = "A.mp3";
			break;
		case 2: inputFile = "B.mp3";
			break;
		case 3: inputFile = "C.mp3";
			break;
	}
return inputFile;
}
int main(int argc, char** argv) {
  // Begin by setting up our usage environment:
  TaskScheduler* scheduler = BasicTaskScheduler::createNew();
  env = BasicUsageEnvironment::createNew(*scheduler);

  UserAuthenticationDatabase* authDB = NULL;
#ifdef ACCESS_CONTROL
  // To implement client access control to the RTSP server, do the following:
  authDB = new UserAuthenticationDatabase;
  authDB->addUserRecord("username1", "password1"); // replace these with real strings
  // Repeat the above with each <username>, <password> that you wish to allow
  // access to the server.
#endif

  // Create the RTSP server:
  RTSPServer* rtspServer = RTSPServer::createNew(*env, 8554, authDB, 45);
  if (rtspServer == NULL) {
    *env << "Failed to create RTSP server: " << env->getResultMsg() << "\n";
    exit(1);
  }

  char const* descriptionString = "Session streamed by \"testOnDemandRTSPServer\"";
{
    char const* streamName = "mp3AudioTest";
    char* inputFileName=argv[100];
    ServerMediaSession* sms
      = ServerMediaSession::createNew(*env, streamName, streamName, descriptionString);
    Boolean useADUs = False;
    Interleaving* interleaving = NULL;
#ifdef STREAM_USING_ADUS 
    useADUs = True;
#ifdef INTERLEAVE_ADUS
    unsigned char interleaveCycle[] = {0,2,1,3}; // or choose your own...
    unsigned const interleaveCycleSize
      = (sizeof interleaveCycle)/(sizeof (unsigned char));
    interleaving = new Interleaving(interleaveCycleSize, interleaveCycle); 
#endif
#endif
    sms->addSubsession(MP3AudioFileServerMediaSubsession::createNew(*env, inputFileName, reuseFirstSource, useADUs, interleaving));
    rtspServer->addServerMediaSession(sms);
    announceStream(rtspServer, sms, streamName, inputFileName);
  }
env->taskScheduler().doEventLoop(); // does not return

  return 0; // only to prevent compiler warning
}

static void announceStream(RTSPServer* rtspServer, ServerMediaSession* sms,
			   char const* streamName, char* inputFileName) {
  char* url = rtspServer->rtspURL(sms);
  UsageEnvironment& env = rtspServer->envir(); 
 int choice;
	env << "Which file to play?\r\n";
	env << "Menu : \n";
	env << "1. A\n";
	env << "2. B\n";
	env << "3. C\n";
	scanf("%d", &choice);

  inputFileName = getFileName(choice);
  env << "\n\"" << streamName << "\" stream, from the file \""
      << inputFileName << "\"\n";
  env << "Play this stream using the URL \"" << url << "\"\n";
	
	
  delete[] url;
}

After that I compiled it, and the output is like this :

Which file to play?
Menu : 
1. A
2. B
3. C
3

"mp3AudioTest" stream, from the file "C.mp3"
Play this stream using the URL "rtsp://10.10.10.101:8554/mp3AudioTest"
Segmentation fault (core dumped)

Ok. Now I talk about the functionality of the program :
This is the program that let the user choose the audio file, then play. I pull up the server first, choose the file name (as you see, I enter "3" and the file name returned is "C.mp3"). After that, I open the client and play the file. But it can't play and server returned message : Segmentation fault (core dumped)

I do a Google search and I found that this caused by pointer error (using non-pointer for pointer, maybe not exactly what I read, because I can't find the article which talk about this again). I re-check my program, but can't see where is the pointer error.

May everyone give me a hand on this problem? Thanks a lot.

Dani AI

Generated

Short diagnosis and practical fixes.

The crash came from a combination of an out‑of‑bounds/incorrect filename pointer and the order in which the session was created. correctly flagged the argv indexing problem, and correctly suggested preferring safer string types. In the thread the program constructs the media/subsession before the chosen filename is actually set; changing a local parameter inside the announce routine does not change the value that was already passed to the server, so the server ends up using an invalid pointer and later memory access fails.

Concrete, low‑risk changes that resolve this class of segfaults:

  • Do not use an out‑of‑range argv index. If command‑line input is used, check argc before reading argv[n]. Prefer not to mix argv and interactive input.
  • Gather the chosen filename first, store it in a std::string (or a const char* that points at a persistent buffer), then create the ServerMediaSession/subsession using filename.c_str(). If the library stores the pointer rather than copying it, keep the std::string alive for the lifetime of the session.
  • Make getFileName return a std::string or a const char to a persistent object; avoid returning pointers to local buffers or relying on writable char for string literals.
  • Replace scanf with safer C++ input (std::cin) or the usage‑environment API; scanf can leave stdin in an unexpected state.

Quick example of the safe flow (illustrative):

int choice;
std::string filename;
std::cout << "1) A.mp3  2) B.mp3  3) C.mp3\n";
if (!(std::cin >> choice)) choice = 1;
filename = (choice == 2) ? "B.mp3" : (choice == 1 ? "A.mp3" : "C.mp3");
// create the media session/subsession now, using filename.c_str()
create_media_session(filename.c_str());

Debugging tips: build with -g and run under gdb to get a backtrace, or use AddressSanitizer (-fsanitize=address) and Valgrind to find invalid reads/writes. Also confirm that freeing the RTSP URL (delete[] url) matches the library contract — consult the API docs or avoid manual deletion if the API returns an owned smart pointer. The OP () reported success after moving the selection code before session creation, which confirms the root cause and the appropriate fix.

Recommended Answers

All 7 Replies

>> char* inputFileName=argv[100];
Huh? Do you pass over 100 arguments on the command line to your program? Not very likely, so that are you trying to do here ?

Hmm...only 1 argument. I thought I typed wrong here. So how can I correct the message "Segmentation fault (core dumped)"?

> I thought I typed wrong here.
What!!???

You mean that code isn't a direct copy/paste from your code editor?

Because if it isn't, you're wasting everyone's time.

> char* url = rtspServer->rtspURL(sms);
Post that method.
Are you sure that delete [] url; is valid at that point?

> char* inputFileName=argv[100];
Notwithstanding the point AD made, you also seem to use this as some local variable for reading in user input as well.
Try using a true std::string for reading input.
Ditto with your use of scanf, use a C++ equivalent.

The code is the same to my code editor. This is the code that I modified from another code. The original one works well, but can play only the file which has the name defined in the code. If I want to play another file, I want to go back to the code, change the name, compile again then play. It's not convenient, so I want to modify the source code to be able to play different files. The lines I added are ;

char* getFileName(int choice);
char* getFileName(int choice)
{
	char* inputFile = "";
	switch(choice){
		case 1: inputFile = "A.mp3";
			break;
		case 2: inputFile = "B.mp3";
			break;
		case 3: inputFile = "C.mp3";
			break;
	}
return inputFile;
}

And :

char* inputFileName=argv[100]; (this is actually argv[1], not [100])

And

int choice;
	env << "Which file to play?\r\n";
	env << "Menu : \n";
	env << "1. A\n";
	env << "2. B\n";
	env << "3. C\n";
	scanf("%d", &choice);

  inputFileName = getFileName(choice);

If I take out all these, the code will work again, but can't choose different files.

: yes, I use the "char* inputFileName=argv[1] " as the variable to read the user input.
Is it the error caused by this variable?

Well if your user input is going into where argv[1] is stored, and you type in a longer name, or you don't supply an argument and you type something (anything) in, then yes, your code is in trouble.

I has just changed positions of codes and add some lines, it works now. Thank Salem for your advice.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.