0

I'm using nanomsg for request/receive and the code I have works just fine when I compiled it using a Makefile. However when I try using cmake, it compiles just fine but runs into Segmentation Fault when trying to send a message.

Does anyone know what's going on? I'm also unsure if the issue is in my cmake file or in the .cc files.

Here is a minimal working example.

request.cc (its .h file is omitted here)

Requester::Requester(const char* url) {
  int socket = nn_socket(AF_SP, NN_REQ);
  assert(socket >= 0);
  assert(nn_connect (socket, url) >= 0);
}

Requester::~Requester() {
  nn_shutdown(socket, 0);
}

const char* Requester::request_for_sentence(const char* sentence){

  int size_sentence = strlen(sentence) + 1;
  int bytes = nn_send(socket, sentence, size_sentence, 0); # segmentation fault occurs here
  assert(bytes == size_sentence);
  char *buf = NULL;
  bytes = nn_recv(socket, &buf, NN_MSG, 0);
  assert(bytes >= 0);
  printf("REQUESTER RECEIVED %s\n", buf);
  return buf;
}

request_test.cc

int main(int argc, char** argv) {
  extractor::Requester my_requester("ipc:///tmp/extractor.ipc");
  const char* output = my_requester.request_for_sentence("some input");
  cerr << "output: " << output << endl;
  return 0;
}

receiver.cc

int main(int argc, char** argv) {
  const char* url = "ipc:///tmp/extractor.ipc";
  int socket = nn_socket (AF_SP, NN_REP);
  assert(socket >= 0);
  assert(nn_bind (socket, url) >= 0); 
  while(1){

    char *buf = NULL;
    int bytes = nn_recv(socket, &buf, NN_MSG, 0);
    assert (bytes >= 0);

    const char* grammar_for_sentence = extract_for_sentence(buf);

    cerr << grammar_for_sentence << endl;

    int size_grammar = strlen(grammar_for_sentence) + 1; // '\0' too
    bytes = nn_send(socket, grammar_for_sentence, size_grammar, 0);
    assert(bytes == size_grammar);

    nn_freemsg (buf);
  }

  return 0;
}

Makefile that works:

CC=g++
CFLAGS = -L$HOME/opt/lib -I$HOME/opt/include -lnanomsg

all : run_test run_extract_daemon

run_test : extract_request_test.cc extract_request.o
    $(CC) $(CFLAGS) -o run_test extract_request_test.cc extract_request.o -I.

run_extract_daemon : extract_daemon.cc
    $(CC) $(CFLAGS) -o run_extract_daemon extract_daemon.cc

extract_request.o : extract_request.cc extract_request.h
    $(CC) $(CFLAGS) -c extract_request.cc
clean :
    rm run_test run_extract_daemon extract_request.o

CMakeLists.txt that doesn't work:

find_package(nanomsg)
if(NANOMSG_FOUND)
  include_directories(${NANOMSG_INCLUDE_DIR})    
  set(extract_request_test_SRCS extract_request_test.cc)
  add_executable(run_extractor_request_test ${extract_request_test_SRCS})
  target_link_libraries(run_extractor_request_test extractor ${NANOMSG_LIBRARIES})

  set(extract_daemon_SRCS extract_daemon.cc)
  add_executable(run_daemon ${extract_daemon_SRCS})
  target_link_libraries(run_daemon extractor ${NANOMSG_LIBRARIES})
endif(NANOMSG_FOUND)

set(extractor_STAT_SRCS
    extract_request.cc
    extract_request.h)


add_library(extractor STATIC ${extractor_STAT_SRCS})
carence
  • 87
  • 9
  • Why do you think that your issue has anything to do with cmake? Maybe your program has a bug that introduces `undefined behavior`. – PaulMcKenzie Jul 08 '15 at 09:34
  • I was considering it as it works fine if I directly write the Makefile and this is my first time using cmake. – carence Jul 08 '15 at 09:44
  • 1
    Your issue has nothing to do with cmake. Your program has bugs that introduces undefined behavior, mainly improper function calling and pointer usage. – PaulMcKenzie Jul 08 '15 at 09:44
  • Okay, thanks for pointing me in the right direction. – carence Jul 08 '15 at 09:48
  • The only way cmake can make a difference is if your final build is different (in terms of libraries that are linked to) than with a make file. In other words, your two different builds should result in the exact same executable image. – PaulMcKenzie Jul 08 '15 at 10:02
  • Just a general hint when moving from make to CMake: CMake auto-configures your build environment with some default compile and link flags. And the [default build type is Debug](http://stackoverflow.com/questions/27086145/what-is-the-default-build-configuration-of-cmake). What helps when doing the move to CMake is using [verbose makefiles](http://stackoverflow.com/questions/2670121/using-cmake-with-gnu-make-how-can-i-see-the-exact-commands) to see the commands executed and add `include(CMakePrintSystemInformation.cmake)` after your `project()` to see the major CMake variables used. – Florian Jul 08 '15 at 10:05
  • @claurel In your `Requestor` constructor, you do this: `int socket = nn_socket(AF_SP, NN_REQ);` The `socket` here is a local variable, not a member variable. Then in your `Requestor` destructor, you do this: `nn_shutdown(socket, 0);` So it looks like you're issuing a `shutdown` on a `socket` variable which was never initialized. Unless it is a typo of some sort, that is one potential issue. – PaulMcKenzie Jul 08 '15 at 10:09
  • @Florian: Thanks for the tip! – carence Jul 08 '15 at 10:25
  • @PaulMcKenzie Thanks for spotting that! It works now. You mentioned improper function calling and pointer usage, can you tell me where that happens? – carence Jul 08 '15 at 10:26

0 Answers0