2016-12-06 1 views
4

내가 실행중인 일부 C++ 코드에 문제가 있습니다. 기본적으로, 그것은 대부분의 입력과 잘 작동하지만, 내 주요 기능이 돌아 오면 특정 입력으로 세그 폴트됩니다. 이것은 수수께끼 같은 일이었습니다. 내가 스택 추적을 얻을 수는 segfault의 실행을 중지하고,이 반환 :부스트 :: Regex Segfault (내 생각 엔)

#0 malloc_consolidate() at /build/eglibc-oGUzwX/eglibc-2.19/malloc/malloc.c:4151 
#1 _int_free() at /build/eglibc-oGUzwX/eglibc-2.19/malloc/malloc.c:4057 
#2 boost::re_detail::mem_block_cache::~mem_block_cache()() at /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.54.0 
#3 __cxa_finalize() at /build/eglibc-oGUzwX/eglibc-2.19/stdlib/cxa_finalize.c:56 
#4 ??() at /usr/lib/x86_64-linux-gnu/libboost_regex.so.1.54.0 
#5 ??() at 
#6 _dl_fini() at /build/eglibc-oGUzwX/eglibc-2.19/elf/dl-fini.c:252 

이 날 내가 부스트 정규식 잘못된 일을해야한다고 생각했다,하지만 내 인생 내가 할 수 없습니다 그것을 알아 내라. 정규식을 사용하는 방법은 사용자가 문자열을 입력 할 수 있다는 것입니다. 이러한 문자열은 일반 텍스트 일 ​​수도 있고 정규 표현식 일 수도 있습니다. 이 때문에 나는 기본적으로 정규 표현식으로 모든 입력과 상호 작용합니다. 그러나 일반 텍스트로 의도되었지만 정규 표현식과 다르게 해석 될 수있는 문자가있는 문자열을 사용자가 제공하면 어떻게됩니까? 내가하는 일은 모든 일반 텍스트 입력 문자열을 살펴보고 모든 문자를 이스케이프 처리하는 것입니다.

다음은 내가 작업하고있는 코드입니다. 이것은 내 메인입니다 :

int 
main(int argc, char * argv[]) 
{ 

    // Process input arguments 
    // The desired input is numVertices (int), graph density (double between 0 and 1), halfLoss (double), total loss (double), 
    // position expanse (double, m), velocity expanse (double, m/s) 
    int num_vertices; 
    double graph_density ; 
    double half_loss; 
    double total_loss; 
    double position_expanse; 
    double velocity_expanse; 

    if (argc == 1) 
    { 
     num_vertices = 48; 
     graph_density = 1; 
     half_loss = 200000; 
     total_loss = 400000; 
     position_expanse = 400000; 
     velocity_expanse = 10000; 
    } 
    else 
    { 
     if (argc != 7) 
     { 
      std::cerr << "Need 6 input arguments" << std::endl; 
      return 1; 
     } 

     std::istringstream ss(argv[1]); 
     num_vertices; 
     if (!(ss >> num_vertices)) 
      std::cerr << "First input must be an integer" << std::endl; 

     graph_density = read_double_input(argv[2]); 
     half_loss = read_double_input(argv[3]); 
     total_loss = read_double_input(argv[4]); 
     position_expanse = read_double_input(argv[5]); 
     velocity_expanse = read_double_input(argv[6]); 
    } 

    // Determine how many edges to create 
    int num_edges = (int) ((graph_density * num_vertices * (num_vertices - 1)) + 0.5); 

    // Create the edges 
    int edges_created = 0; 
    std::set<std::pair<int, int> > edge_set; 
    while (edge_set.size() < num_edges) 
    { 

     // Pick a random start vertex and end vertex 
     int start_vertex = rand() % num_vertices; 
     int end_vertex = rand() % num_vertices; 

     // Make sure the start and end vertices are not equal 
     while (start_vertex == end_vertex) 
     { 
      end_vertex = rand() % num_vertices; 
     } 

     // Insert the new edge into our set of edges 
     edge_set.insert(std::pair<int, int>(start_vertex, end_vertex)); 

    } 

    // Create connection handler 
    ConnectionHandler conn_handler; 

    // Create lists for from and to vertices 
    std::vector<std::string> from_list; 
    std::vector<std::string> to_list; 

    // Add connections to from and to lists 
    for (std::set<std::pair<int, int> >::const_iterator edge_it = edge_set.begin(), end_it = edge_set.end(); edge_it != end_it; ++edge_it) 
    { 
     int start_vertex = edge_it->first; 
     int end_vertex = edge_it->second; 
     from_list.push_back("Radio" + int_to_string(start_vertex)); 
     to_list.push_back("Radio" + int_to_string(end_vertex)); 
    } 

    // Read the list into the connection handler 
    conn_handler.read_connection_list(true, from_list, to_list);  
    return 0; 

} 

이 코드에는 내가 만든이 ConnectionHandler 객체가 있습니다.

#ifndef CLCSIM_CONNECTIONHANDLER_HPP_ 
#define CLCSIM_CONNECTIONHANDLER_HPP_ 

#include <models/network/NetworkTypes.hpp> 
#include <generated/xsd/NetworkModelInterfaceConfig.hpp> 

namespace clcsim 
{ 

typedef std::map<std::string, std::set<std::string> > ConnectionFilter; 

class ConnectionHandler 
{ 

public: 

    ConnectionHandler(); 
    ~ConnectionHandler(); 

    void read_connection_list(const bool is_white_list, const std::vector<std::string> &from_radios, const std::vector<std::string> &to_radios); 


private: 

    ConnectionFilter filter_; 
    std::set<std::string> from_list_; 
    std::set<std::string> to_list_; 
    bool is_white_list_; 

}; 

} // namespace clcsim 

#endif // CLCSIM_CONNECTIONHANDLER_HPP_ 

을 그리고 여기 소스입니다 : 여기에 대한 헤더입니다 너무 많은 코드를

#include <models/network/ConnectionHandler.hpp> 
#include <oasis/framework/exceptions/ConfigurationException.h> 
#include <boost/regex.hpp> 

namespace clcsim 
{ 

ConnectionHandler:: 
ConnectionHandler() 
{ 
} 

ConnectionHandler:: 
~ConnectionHandler() 
{ 
    std::cout << "Destructing conn handler" << std::endl; 
} 

void 
ConnectionHandler:: 
read_connection_list(
    const bool is_white_list, 
    const std::vector<std::string> &from_radios, 
    const std::vector<std::string> &to_radios) 
{ 

    std::cout << "Reading the connection list" << std::endl; 

    // Make sure the size of both the input vectors are the same 
    std::size_t from_radio_size = from_radios.size(); 
    std::size_t to_radio_size = to_radios.size(); 
    if (from_radio_size != to_radio_size) 
    { 
     throw ofs::ConfigurationException("Error while initializing the " 
              "Network model: " 
              "Connections in from/to lists don't align" 
             ); 
    } 

    // Create a regular expression/replacement to find all characters in a non-regular expression 
    // that would be interpreted as special characters in a regular expression. Replace them with 
    // escape characters 
    const boost::regex esc("[.$|()\\[\\]{}*+?\\\\]"); 
    const std::string rep("\\\\&"); 

    // Iterate through the specified connections 
    for (int i = 0; i < from_radio_size; ++i) 
    { 

     std::string from_string = boost::regex_replace(from_radios[i], esc, rep, boost::match_default | boost::format_sed); 
     std::string to_string = boost::regex_replace(to_radios[i], esc, rep, boost::match_default | boost::format_sed); 
     //std::cout << "From " << from_string << " to " << to_string << std::endl; 
     filter_[from_string].insert(to_string); 
     //filter_[from_radios.at(i)].insert(to_radios.at(i)); 
    } 

    std::cout << "Got here" << std::endl; 

} 


} // namespace clcsim 

죄송합니다.

boost :: regex를 사용하여 segfaults와 관련된 비슷한 스레드를 보았습니다. 이 예제에서 사용자는 방금 정규 표현식을 만들고이를 일치시키고 오류가 발생하는 아주 간단한 코드를 가지고있었습니다. Boost 버전 관리와 관련된 문제가 발견되었습니다. 그런 종류의 오류를 복제 할 수 있는지 알아보기 위해 노력했지만 간단한 예제는 저에게 잘 돌아갔습니다. 그래서 ... 나는 꽤 난처한 처지입니다. 나는 정말 어떤 도움을 주셔서 감사합니다!

+1

"나는 세그 폴트에서 뛰었습니다."라는 말의 의미가 불확실합니다. segfault가 있으면 * 시스템 *이 실행을 중지합니다. 디버거에서 실행중인 경우 실제로는 오류의 위치를 ​​보여주는 스택 추적을 가져올 수 있어야하지만 시스템이 시작하기 전에 프로그램을 중지하면 스택 추적이 오류 추적의 특징을 알 수 없습니다. 아직 세그 폴트의 위치. –

+0

죄송합니다. 예, 저를 시정 해 주셔서 감사합니다. 디버거에서 실행 한 다음 오류가 발생하여 스택 추적을 제공했습니다. – user2701114

+1

스택 추적에서 eglibc를 봅니다. eglibc 용으로 빌드 된 소프트웨어 스택 (boost, C++ 컴파일러, C++ 런타임 등)이 모두 일관성이 있습니까? glibc 변종이 이제는 중단되었으므로 서로 다른 C 라이브러리에 맞게 작성된 소프트웨어와 라이브러리를 함께 사용하면 문제가 발생할 수 있습니다. –

답변

0

"답변되지 않은"목록에서이를 제거하기 위해 여기 대신 설명에 제공된 대답을 게시 할 것입니다. OP는 eglibc에 링크 된 Boost가 glibc에 링크 된 나머지 코드와 실제로 충돌한다는 제안을 결정했습니다. 따라서 OP는 eglibc 링크 라이브러리가 더 이상 사용되지 않도록 운영 체제를 업그레이드하면 문제가 해결된다는 사실을 발견했습니다.

관련 문제