I made some modifications to this code snippet which is used to send\recieve ICMP packets through ASIO APIs.
Here are the modifications that I made(full code snippet is seen below):
using the standard version API instead of the corresponding API provided by Boost
using std::bind instead of boost::bind
starting to use shared pointer
using a shared pointer which points to pinger(i.e. std::shared_ptr<pinger> sp{new pinger(io_service, argv[1])};) instead of contructing an instance directly by the default constructor of pinger (i.e. pinger p(io_service, argv[1]);).
class pinger derives from std::enabled_shared_from_this<pinger> now
the second argument passed to boost::bind is not a this pointer anymore,I use shared_from_this() to pass a std::shared_pointer to std::bind.For exmple: my code is timer_.async_wait(std::bind(&pinger::start_send, shared_from_this()));, whereas the orignal one is timer_.async_wait(boost::bind(&pinger::handle_timeout, this));.
to avoid calling shared_from_this() in the constructor of class pinger, the start_send(); start_receive(); is moved out of the constructer and a new function named Init() is used to invoke these two aforemetioned functions.
using the non-throwing version asio::raw_socket::send_to and retrying to send ICMP packets when some error occurs.
socket_.send_to(request_buffer.data(), destination_); is replaced by socket_.send_to(request_buffer.data(), destination_, flags, error);
retry to send ICMP packets(by calling timer_.async_wait(std::bind(&pinger::start_send, shared_from_this())); when socket_.send_to faces to an error.
Here is my code snippet(icmp_header.hpp & ipv4_header.hpp are seen here):
#if 1
#include "icmp_header.hpp"
#include "ipv4_header.hpp"
#include <boost/asio.hpp>
#include <functional>
#include <iostream>
#include <istream>
#include <memory>
#include <ostream>
using boost::asio::deadline_timer;
using boost::asio::ip::icmp;
namespace posix_time = boost::posix_time;
class pinger : public std::enable_shared_from_this<pinger> {
public:
pinger(boost::asio::io_service &io_service, const char *destination)
: resolver_(io_service), socket_(io_service, icmp::v4()),
timer_(io_service), sequence_number_(0), num_replies_(0) {
icmp::resolver::query query(icmp::v4(), destination, "");
destination_ = *resolver_.resolve(query);
}
void init() {
start_send();
start_receive();
}
private:
void start_send() {
std::string body("\"Hello!\" from Asio ping.");
// Create an ICMP header for an echo request.
icmp_header echo_request;
echo_request.type(icmp_header::echo_request);
echo_request.code(0);
echo_request.identifier(get_identifier());
echo_request.sequence_number(++sequence_number_);
compute_checksum(echo_request, body.begin(), body.end());
// Encode the request packet.
boost::asio::streambuf request_buffer;
std::ostream os(&request_buffer);
os << echo_request << body;
// Send the request.
time_sent_ = posix_time::microsec_clock::universal_time();
boost::system::error_code error;
boost::asio::socket_base::message_flags flags;
socket_.send_to(request_buffer.data(), destination_, flags, error);
if (error) {
std::cout << "send_to failed1:" << error.message() << std::endl;
std::cout << "send_to failed2:" << std::endl;
timer_.expires_at(time_sent_ + posix_time::seconds(1));
timer_.async_wait(std::bind(&pinger::start_send, shared_from_this()));
} else {
// Wait up to five seconds for a reply.
num_replies_ = 0;
timer_.expires_at(time_sent_ + posix_time::seconds(5));
timer_.async_wait(std::bind(&pinger::handle_timeout, shared_from_this()));
}
}
void handle_timeout() {
if (num_replies_ == 0)
std::cout << "Request timed out" << std::endl;
// Requests must be sent no less than one second apart.
timer_.expires_at(time_sent_ + posix_time::seconds(1));
timer_.async_wait(std::bind(&pinger::start_send, shared_from_this()));
}
void start_receive() {
// Discard any data already in the buffer.
reply_buffer_.consume(reply_buffer_.size());
// Wait for a reply. We prepare the buffer to receive up to 64KB.
socket_.async_receive(reply_buffer_.prepare(65536),
std::bind(&pinger::handle_receive, shared_from_this(),
std::placeholders::_1,
std::placeholders::_2));
}
void handle_receive(boost::system::error_code error, std::size_t length) {
// The actual number of bytes received is committed to the buffer so that we
// can extract it using a std::istream object.
if (error) {
std::cout << "error in handle_receive:"
<< boost::system::system_error(error).what() << std::endl;
}
reply_buffer_.commit(length);
// Decode the reply packet.
std::istream is(&reply_buffer_);
ipv4_header ipv4_hdr;
icmp_header icmp_hdr;
is >> ipv4_hdr >> icmp_hdr;
// We can receive all ICMP packets received by the host, so we need to
// filter out only the echo replies that match the our identifier and
// expected sequence number.
if (is && icmp_hdr.type() == icmp_header::echo_reply &&
icmp_hdr.identifier() == get_identifier() &&
icmp_hdr.sequence_number() == sequence_number_) {
// If this is the first reply, interrupt the five second timeout.
if (num_replies_++ == 0)
timer_.cancel();
// Print out some information about the reply packet.
posix_time::ptime now = posix_time::microsec_clock::universal_time();
std::cout << length - ipv4_hdr.header_length() << " bytes from "
<< ipv4_hdr.source_address()
<< ": icmp_seq=" << icmp_hdr.sequence_number()
<< ", ttl=" << ipv4_hdr.time_to_live()
<< ", time=" << (now - time_sent_).total_milliseconds() << " ms"
<< std::endl;
}
start_receive();
}
static unsigned short get_identifier() {
#if defined(BOOST_WINDOWS)
return static_cast<unsigned short>(::GetCurrentProcessId());
#else
return static_cast<unsigned short>(::getpid());
#endif
}
icmp::resolver resolver_;
icmp::endpoint destination_;
icmp::socket socket_;
deadline_timer timer_;
unsigned short sequence_number_;
posix_time::ptime time_sent_;
boost::asio::streambuf reply_buffer_;
std::size_t num_replies_;
};
int main(int argc, char *argv[]) {
try {
if (argc != 2) {
std::cerr << "Usage: ping <host>" << std::endl;
#if !defined(BOOST_WINDOWS)
std::cerr << "(You may need to run this program as root.)" << std::endl;
#endif
return 1;
}
boost::asio::io_service io_service;
std::shared_ptr<pinger> sp{new pinger(io_service, argv[1])};
sp->init();
io_service.run();
} catch (std::exception &e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
}
#endif
The code snippet above works well when my local network is ok.Here is the output:
32 bytes from 192.168.1.51: icmp_seq=1, ttl=58, time=4 ms
32 bytes from 192.168.1.51: icmp_seq=2, ttl=58, time=3 ms
//omit...
//running a long long time
The program receives a signal SIGABRT and then aborts when I run sudo ifconfig wlp59s0 down on purpose(to make sure whether the program is stable or not). Here is the backstrace I got by GDB
sudo gdb -q ./modified_ping
Reading symbols from ./modified_ping...done.
(gdb) r 192.168.1.51
Starting program: /home/jhon/icmp/build/modified_ping 192.168.1.51
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
32 bytes from 192.168.1.51: icmp_seq=1, ttl=58, time=3 ms
32 bytes from 192.168.1.51: icmp_seq=2, ttl=58, time=4 ms
32 bytes from 192.168.1.51: icmp_seq=3, ttl=58, time=3 ms
32 bytes from 192.168.1.51: icmp_seq=4, ttl=58, time=3 ms //NOTE:manually run `ifconfig down` on purpose
send_to failed1:
send_to failed2:
*** Error in `/home/jhon/icmp/build/modified_ping': double free or corruption (!prev): 0x0000000000699f80 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777f5)[0x7ffff6dc07f5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8038a)[0x7ffff6dc938a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7ffff6dcd58c]
/home/jhon/icmp/build/modified_ping[0x44bcd6]
/home/jhon/icmp/build/modified_ping[0x44ae36]
/home/jhon/icmp/build/modified_ping[0x449b56]
/home/jhon/icmp/build/modified_ping[0x447e09]
/home/jhon/icmp/build/modified_ping[0x445403]
/home/jhon/icmp/build/modified_ping[0x44e005]
/home/jhon/icmp/build/modified_ping[0x43f347]
/home/jhon/icmp/build/modified_ping[0x44de00]
/home/jhon/icmp/build/modified_ping[0x44db4e]
/home/jhon/icmp/build/modified_ping[0x44d6eb]
/home/jhon/icmp/build/modified_ping[0x44d3b6]
/home/jhon/icmp/build/modified_ping[0x44d0d9]
/home/jhon/icmp/build/modified_ping[0x44c9c7]
/home/jhon/icmp/build/modified_ping[0x44c03f]
/home/jhon/icmp/build/modified_ping[0x44b257]
/home/jhon/icmp/build/modified_ping[0x439e94]
/home/jhon/icmp/build/modified_ping[0x43ca93]
/home/jhon/icmp/build/modified_ping[0x43c4e8]
/home/jhon/icmp/build/modified_ping[0x43cdac]
/home/jhon/icmp/build/modified_ping[0x436b34]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7ffff6d69840]
/home/jhon/icmp/build/modified_ping[0x4059a9]
======= Memory map: ========
00400000-00486000 r-xp 00000000 08:02 94506936 /home/jhon/icmp/build/modified_ping
00685000-00686000 r--p 00085000 08:02 94506936 /home/jhon/icmp/build/modified_ping
00686000-00687000 rw-p 00086000 08:02 94506936 /home/jhon/icmp/build/modified_ping
00687000-006b9000 rw-p 00000000 00:00 0 [heap]
7ffff0000000-7ffff0021000 rw-p 00000000 00:00 0
7ffff0021000-7ffff4000000 ---p 00000000 00:00 0
7ffff6d49000-7ffff6f09000 r-xp 00000000 08:02 14029372 /lib/x86_64-linux-gnu/libc-2.23.so
7ffff6f09000-7ffff7109000 ---p 001c0000 08:02 14029372 /lib/x86_64-linux-gnu/libc-2.23.so
7ffff7109000-7ffff710d000 r--p 001c0000 08:02 14029372 /lib/x86_64-linux-gnu/libc-2.23.so
7ffff710d000-7ffff710f000 rw-p 001c4000 08:02 14029372 /lib/x86_64-linux-gnu/libc-2.23.so
7ffff710f000-7ffff7113000 rw-p 00000000 00:00 0
7ffff7113000-7ffff712a000 r-xp 00000000 08:02 14024978 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff712a000-7ffff7329000 ---p 00017000 08:02 14024978 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff7329000-7ffff732a000 r--p 00016000 08:02 14024978 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff732a000-7ffff732b000 rw-p 00017000 08:02 14024978 /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff732b000-7ffff7433000 r-xp 00000000 08:02 14024798 /lib/x86_64-linux-gnu/libm-2.23.so
7ffff7433000-7ffff7632000 ---p 00108000 08:02 14024798 /lib/x86_64-linux-gnu/libm-2.23.so
7ffff7632000-7ffff7633000 r--p 00107000 08:02 14024798 /lib/x86_64-linux-gnu/libm-2.23.so
7ffff7633000-7ffff7634000 rw-p 00108000 08:02 14024798 /lib/x86_64-linux-gnu/libm-2.23.so
7ffff7634000-7ffff77a6000 r-xp 00000000 08:02 44435598 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7ffff77a6000-7ffff79a6000 ---p 00172000 08:02 44435598 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7ffff79a6000-7ffff79b0000 r--p 00172000 08:02 44435598 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7ffff79b0000-7ffff79b2000 rw-p 0017c000 08:02 44435598 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7ffff79b2000-7ffff79b6000 rw-p 00000000 00:00 0
7ffff79b6000-7ffff79b9000 r-xp 00000000 08:02 44441454 /usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0
7ffff79b9000-7ffff7bb8000 ---p 00003000 08:02 44441454 /usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0
7ffff7bb8000-7ffff7bb9000 r--p 00002000 08:02 44441454 /usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0
7ffff7bb9000-7ffff7bba000 rw-p 00003000 08:02 44441454 /usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0
7ffff7bba000-7ffff7bd2000 r-xp 00000000 08:02 14024729 /lib/x86_64-linux-gnu/libpthread-2.23.so
7ffff7bd2000-7ffff7dd1000 ---p 00018000 08:02 14024729 /lib/x86_64-linux-gnu/libpthread-2.23.so
7ffff7dd1000-7ffff7dd2000 r--p 00017000 08:02 14024729 /lib/x86_64-linux-gnu/libpthread-2.23.so
7ffff7dd2000-7ffff7dd3000 rw-p 00018000 08:02 14024729 /lib/x86_64-linux-gnu/libpthread-2.23.so
7ffff7dd3000-7ffff7dd7000 rw-p 00000000 00:00 0
7ffff7dd7000-7ffff7dfd000 r-xp 00000000 08:02 14024795 /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7fcb000-7ffff7fd2000 rw-p 00000000 00:00 0
7ffff7ff6000-7ffff7ff7000 rw-p 00000000 00:00 0
7ffff7ff7000-7ffff7ffa000 r--p 00000000 00:00 0 [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00025000 08:02 14024795 /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffd000-7ffff7ffe000 rw-p 00026000 08:02 14024795 /lib/x86_64-linux-gnu/ld-2.23.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Program received signal SIGABRT, Aborted.
0x00007ffff6d7e438 in __GI_raise (sig=sig#entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
54 ../sysdeps/unix/sysv/linux/raise.c: no such file or folder
(gdb) bt
#0 0x00007ffff6d7e438 in __GI_raise (sig=sig#entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54
#1 0x00007ffff6d8003a in __GI_abort () at abort.c:89
#2 0x00007ffff6dc07fa in __libc_message (do_abort=do_abort#entry=2, fmt=fmt#entry=0x7ffff6ed9fd8 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3 0x00007ffff6dc938a in malloc_printerr (ar_ptr=<optimized out>, ptr=<optimized out>, str=0x7ffff6eda108 "double free or corruption (!prev)", action=3) at malloc.c:5020
#4 _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3874
#5 0x00007ffff6dcd58c in __GI___libc_free (mem=<optimized out>) at malloc.c:2975
#6 0x000000000044bcd6 in __gnu_cxx::new_allocator<char>::deallocate (this=0x7fffffffdd98, __p=0x699f80 "\b") at /usr/include/c++/4.9/ext/new_allocator.h:110
#7 0x000000000044ae36 in std::allocator_traits<std::allocator<char> >::deallocate (__a=..., __p=0x699f80 "\b", __n=128) at /usr/include/c++/4.9/bits/alloc_traits.h:514
#8 0x0000000000449b56 in std::_Vector_base<char, std::allocator<char> >::_M_deallocate (this=0x7fffffffdd98, __p=0x699f80 "\b", __n=128) at /usr/include/c++/4.9/bits/stl_vector.h:178
#9 0x0000000000447e09 in std::_Vector_base<char, std::allocator<char> >::~_Vector_base (this=0x7fffffffdd98, __in_chrg=<optimized out>) at /usr/include/c++/4.9/bits/stl_vector.h:160
#10 0x0000000000445403 in std::vector<char, std::allocator<char> >::~vector (this=0x7fffffffdd98, __in_chrg=<optimized out>) at /usr/include/c++/4.9/bits/stl_vector.h:425
#11 0x000000000044e005 in boost::asio::basic_streambuf<std::allocator<char> >::~basic_streambuf (this=0x7fffffffdd50, __in_chrg=<optimized out>)
at /usr/include/boost/asio/basic_streambuf.hpp:111
#12 0x000000000043f347 in pinger::start_send (this=0x698d50) at /home/jhon/icmp/src/main.cpp:42
#13 0x000000000044de00 in std::_Mem_fn<void (pinger::*)()>::_M_call<std::shared_ptr<pinger>&> (this=0x7fffffffe140, __ptr=std::shared_ptr (count 4, weak 1) 0x698d50)
at /usr/include/c++/4.9/functional:526
#14 0x000000000044db4e in std::_Mem_fn<void (pinger::*)()>::operator()<std::shared_ptr<pinger>&, , void>(std::shared_ptr<pinger>&) const (this=0x7fffffffe140,
__object=std::shared_ptr (count 4, weak 1) 0x698d50) at /usr/include/c++/4.9/functional:578
#15 0x000000000044d6eb in std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)>::__call<void, boost::system::error_code const&, 0ul>(std::tuple<boost::system::error_code const&>&&, std::_Index_tuple<0ul>) (this=0x7fffffffe140, __args=<unknown type in /home/jhon/icmp/build/modified_ping, CU 0xee6ae, DIE 0x1264e2>)
at /usr/include/c++/4.9/functional:1264
#16 0x000000000044d3b6 in std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)>::operator()<boost::system::error_code const&, void>(boost::system::error_code const&) (
this=0x7fffffffe140) at /usr/include/c++/4.9/functional:1323
#17 0x000000000044d0d9 in boost::asio::detail::binder1<std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)>, boost::system::error_code>::operator()() (this=0x7fffffffe140)
---Type <return> to continue, or q <return> to quit---
at /usr/include/boost/asio/detail/bind_handler.hpp:47
#18 0x000000000044c9c7 in boost::asio::asio_handler_invoke<boost::asio::detail::binder1<std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)>, boost::system::error_code> >(boost::asio::detail::binder1<std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)>, boost::system::error_code>&, ...) (function=...)
at /usr/include/boost/asio/handler_invoke_hook.hpp:69
#19 0x000000000044c03f in boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder1<std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)>, boost::system::error_code>, std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)> >(boost::asio::detail::binder1<std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)>, boost::system::error_code>&, std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)>&) (function=..., context=...) at /usr/include/boost/asio/detail/handler_invoke_helpers.hpp:37
#20 0x000000000044b257 in boost::asio::detail::wait_handler<std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)> >::do_complete(boost::asio::detail::task_io_service*, boost::asio::detail::task_io_service_operation*, boost::system::error_code const&, unsigned long) (owner=0x698c70, base=0x699af0) at /usr/include/boost/asio/detail/wait_handler.hpp:70
#21 0x0000000000439e94 in boost::asio::detail::task_io_service_operation::complete (this=0x699af0, owner=..., ec=..., bytes_transferred=0)
at /usr/include/boost/asio/detail/task_io_service_operation.hpp:38
#22 0x000000000043ca93 in boost::asio::detail::task_io_service::do_run_one (this=0x698c70, lock=..., this_thread=..., ec=...) at /usr/include/boost/asio/detail/impl/task_io_service.ipp:372
#23 0x000000000043c4e8 in boost::asio::detail::task_io_service::run (this=0x698c70, ec=...) at /usr/include/boost/asio/detail/impl/task_io_service.ipp:149
#24 0x000000000043cdac in boost::asio::io_service::run (this=0x7fffffffe360) at /usr/include/boost/asio/impl/io_service.ipp:59
#25 0x0000000000436b34 in main (argc=2, argv=0x7fffffffe498) at /home/jhon/icmp/src/main.cpp:155
Valgrind:
Thanks to #Basile Starynkevitch.
I try to use valgrind to figure out the problem.I add add_compile_options(-Wall -Wextra) in the CMakeLists.txt(set (CMAKE_BUILD_TYPE debug) has already been there when debugging with GDB). I recompile the code sippet above and run it with sudo valgrind .... But what surprises me is that no signal is received now.
Here is the output which is seen in the terminal (with valgrind on Ubuntu 16.04):
sudo valgrind --log-file=valgrind.log --error-limit=no --leak-check=full --tool=memcheck --show-reachable=yes ./modified_ping 192.168.1.51
32 bytes from 192.168.1.51: icmp_seq=1, ttl=58, time=90 ms
32 bytes from 192.168.1.51: icmp_seq=2, ttl=58, time=7 ms
32 bytes from 192.168.1.51: icmp_seq=3, ttl=58, time=11 ms
32 bytes from 192.168.1.51: icmp_seq=4, ttl=58, time=4 ms
32 bytes from 192.168.1.51: icmp_seq=5, ttl=58, time=3 ms
32 bytes from 192.168.1.51: icmp_seq=6, ttl=58, time=2 ms
send_to failed1:
send_to failed2:
send_to failed1:
send_to failed2:
send_to failed1:
send_to failed2:
//omit...
Here is what the valgrind.log contains:
NOTE:1.since the program runs infinitely with valgrind, the program is stopped by CTRL+C. It's strange that the same binary program still encounters SIGABRT with sudo gdb ... when ifconfig down is called in purpose.
2.The log is huge, full log is seen at here.
sudo valgrind --log-file=valgrind.log --error-limit=no --leak-check=full --tool=memcheck --show-reachable=yes ./modified_ping 192.168.1.51
==9362== Memcheck, a memory error detector
==9362== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==9362== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==9362== Command: ./modified_ping 192.168.1.51
//...full log is seen at https://coliru.stacked-
==9362== 1,265 bytes in 55 blocks are definitely lost in loss record 18 of 20
==9362== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9362== by 0x505823E: ??? (in /usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0)
==9362== by 0x5058BFD: ??? (in /usr/lib/x86_64-linux-gnu/libboost_system.so.1.58.0)
==9362== by 0x43731A: boost::system::error_code::message() const (error_code.hpp:357)
==9362== by 0x43F0E9: pinger::start_send() (main.cpp:53)
==9362== by 0x44DDFF: void std::_Mem_fn<void (pinger::*)()>::_M_call<std::shared_ptr<pinger>&>(std::shared_ptr<pinger>&, void const volatile*) const (in /home/jhon/icmp/build/modified_ping)
==9362== by 0x44DB4D: void std::_Mem_fn<void (pinger::*)()>::operator()<std::shared_ptr<pinger>&, , void>(std::shared_ptr<pinger>&) const (functional:578)
==9362== by 0x44D6EA: void std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)>::__call<void, boost::system::error_code const&, 0ul>(std::tuple<boost::system::error_code const&>&&, std::_Index_tuple<0ul>) (functional:1264)
==9362== by 0x44D3B5: void std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)>::operator()<boost::system::error_code const&, void>(boost::system::error_code const&) (functional:1323)
==9362== by 0x44D0D8: boost::asio::detail::binder1<std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)>, boost::system::error_code>::operator()() (bind_handler.hpp:47)
==9362== by 0x44C9C6: void boost::asio::asio_handler_invoke<boost::asio::detail::binder1<std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)>, boost::system::error_code> >(boost::asio::detail::binder1<std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)>, boost::system::error_code>&, ...) (handler_invoke_hook.hpp:69)
==9362== by 0x44C03E: void boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder1<std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)>, boost::system::error_code>, std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)> >(boost::asio::detail::binder1<std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)>, boost::system::error_code>&, std::_Bind<std::_Mem_fn<void (pinger::*)()> (std::shared_ptr<pinger>)>&) (handler_invoke_helpers.hpp:37)
==9362==
==9362== 65,536 bytes in 1 blocks are still reachable in loss record 19 of 20
==9362== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9362== by 0x44BD8B: __gnu_cxx::new_allocator<char>::allocate(unsigned long, void const*) (new_allocator.h:104)
==9362== by 0x44AEB9: std::allocator_traits<std::allocator<char> >::allocate(std::allocator<char>&, unsigned long) (alloc_traits.h:488)
==9362== by 0x449CBB: std::_Vector_base<char, std::allocator<char> >::_M_allocate(unsigned long) (stl_vector.h:170)
==9362== by 0x447F2D: std::vector<char, std::allocator<char> >::_M_default_append(unsigned long) (vector.tcc:557)
==9362== by 0x44547E: std::vector<char, std::allocator<char> >::resize(unsigned long) (stl_vector.h:676)
==9362== by 0x445C4F: boost::asio::basic_streambuf<std::allocator<char> >::reserve(unsigned long) (basic_streambuf.hpp:326)
==9362== by 0x442D04: boost::asio::basic_streambuf<std::allocator<char> >::prepare(unsigned long) (basic_streambuf.hpp:207)
==9362== by 0x43F6B5: pinger::start_receive() (main.cpp:82)
==9362== by 0x43EDE1: pinger::init() (main.cpp:26)
==9362== by 0x436B27: main (main.cpp:154)
==9362==
==9362== 72,704 bytes in 1 blocks are still reachable in loss record 20 of 20
==9362== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9362== by 0x52E4EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==9362== by 0x40106F9: call_init.part.0 (dl-init.c:72)
==9362== by 0x401080A: call_init (dl-init.c:30)
==9362== by 0x401080A: _dl_init (dl-init.c:120)
==9362== by 0x4000C69: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==9362== by 0x1: ???
==9362== by 0xFFF000652: ???
==9362== by 0xFFF000662: ???
==9362==
==9362== LEAK SUMMARY:
==9362== definitely lost: 1,265 bytes in 55 blocks
==9362== indirectly lost: 0 bytes in 0 blocks
==9362== possibly lost: 0 bytes in 0 blocks
==9362== still reachable: 139,978 bytes in 19 blocks
==9362== suppressed: 0 bytes in 0 blocks
==9362==
==9362== For counts of detected and suppressed errors, rerun with: -v
==9362== Use --track-origins=yes to see where uninitialised values come from
==9362== ERROR SUMMARY: 337 errors from 5 contexts (suppressed: 0 from 0)
What's more, it's strange that no signal would be recieved anymore if std::cout << "send_to failed1:" << error.message() << std::endl; is commented out when sudo ifconfig wlp59s0 down has been called. I don't think the problem is with this expression.But I really can't figure out where goes wrong. Could somebody shed some light on this matter?
(gdb) make //after commenting out `std::cout << "send_to failed1:" << error.message() << std::endl;`
[100%] Built target modified_ping
(gdb) r 192.168.1.51
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/jhon/icmp/build/modified_ping 192.168.1.51
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
32 bytes from 192.168.1.51: icmp_seq=1, ttl=58, time=4 ms
32 bytes from 192.168.1.51: icmp_seq=2, ttl=58, time=7 ms
32 bytes from 192.168.1.51: icmp_seq=3, ttl=58, time=2 ms
32 bytes from 192.168.1.51: icmp_seq=4, ttl=58, time=3 ms
32 bytes from 192.168.1.51: icmp_seq=5, ttl=58, time=3 ms
32 bytes from 192.168.1.51: icmp_seq=6, ttl=58, time=4 ms
32 bytes from 192.168.1.51: icmp_seq=7, ttl=58, time=4 ms
32 bytes from 192.168.1.51: icmp_seq=8, ttl=58, time=5 ms
32 bytes from 192.168.1.51: icmp_seq=9, ttl=58, time=3 ms
32 bytes from 192.168.1.51: icmp_seq=10, ttl=58, time=2 ms
send_to failed2:
send_to failed2:
send_to failed2:
send_to failed2:
send_to failed2:
send_to failed2:
send_to failed2:
send_to failed2:
send_to failed2:
send_to failed2:
send_to failed2:
send_to failed2:
send_to failed2:
send_to failed2:
Extra Information:
I am using boost-1.58 which is installed by sudo apt-get install libboost-all-dev on ubuntu16.04.
UPDATED:
Thanks to #273K's generous help.
But the double free or corruption seems not caused by the wrong declaration of handle_receive() because even if the program which does not invoke handle_receive() anymore still faces a similar problem. Here is the backtrace.
I tried your code. The first error faced: error C4700: uninitialized local variable 'flags' used. I have corrected the definition:
boost::asio::socket_base::message_flags flags{};
You have extended void handle_receive(std::size_t length) from the example to
void handle_receive(boost::system::error_code error, std::size_t length). This is incorrect. According to the manual basic_raw_socket::async_receive, it must receive error by const reference.
void handle_receive(const boost::system::error_code &error,
std::size_t length)
After fixing those errors, the SIGABRT went away.
error.message() is supposed to access error by reference, but your definition directs the compiler to access error on the stack, that results in stack memory corruption, because the caller of handle_receive places sizeof(void*) bytes on the stack or in a CPU register, but error.message() uses sizeof(boost::system::error_code) bytes on the stack.
The line expression
boost::system::system_error(error)
could be
error.message()
Now, the fact that it crashes gives me the idea that you might be finding conflicting/incompatible versions of Boost System at runtime vs. at compile time. I know that boost::error_code received some layout-incompatible changes over time.
Another source of such compatibility problem is when the linked libraries are built with very different compiler flags.
Use tools like ldd to check what libraries are actually found at runtime, and whether there are surprises. Also, check the preprocessed source (or e.g. BOOST_VERSION) to see that no surprise header versions are picked up where you didn't expect them.
Inverting the burden of proof, I have created a docker environment to test your code and see that the problem is not reproduced, perhaps you can compare: ubu1604.zip containing:
File Dockerfile
FROM ubuntu:16.04
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get -qyy update
RUN apt-get -qyy install build-essential screen cmake
RUN apt-get -qyy install libboost-all-dev
COPY so /so
# build
WORKDIR /so
RUN cmake . -Wno-dev && make;
ENTRYPOINT [ "/so/test" ]
File so/CMakeLists.txt
SET(CMAKE_CXX_STANDARD 11)
ADD_EXECUTABLE(test test.cpp)
find_package(Boost COMPONENTS system REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
set(CMAKE_CXX_FLAGS -pthread)
target_link_libraries(test ${Boost_LIBRARIES})
File so/icmp_header.hpp
//
// icmp_header.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ICMP_HEADER_HPP
#define ICMP_HEADER_HPP
#include <istream>
#include <ostream>
#include <algorithm>
// ICMP header for both IPv4 and IPv6.
//
// The wire format of an ICMP header is:
//
// 0 8 16 31
// +---------------+---------------+------------------------------+ ---
// | | | | ^
// | type | code | checksum | |
// | | | | |
// +---------------+---------------+------------------------------+ 8 bytes
// | | | |
// | identifier | sequence number | |
// | | | v
// +-------------------------------+------------------------------+ ---
class icmp_header
{
public:
enum { echo_reply = 0, destination_unreachable = 3, source_quench = 4,
redirect = 5, echo_request = 8, time_exceeded = 11, parameter_problem = 12,
timestamp_request = 13, timestamp_reply = 14, info_request = 15,
info_reply = 16, address_request = 17, address_reply = 18 };
icmp_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); }
unsigned char type() const { return rep_[0]; }
unsigned char code() const { return rep_[1]; }
unsigned short checksum() const { return decode(2, 3); }
unsigned short identifier() const { return decode(4, 5); }
unsigned short sequence_number() const { return decode(6, 7); }
void type(unsigned char n) { rep_[0] = n; }
void code(unsigned char n) { rep_[1] = n; }
void checksum(unsigned short n) { encode(2, 3, n); }
void identifier(unsigned short n) { encode(4, 5, n); }
void sequence_number(unsigned short n) { encode(6, 7, n); }
friend std::istream& operator>>(std::istream& is, icmp_header& header)
{ return is.read(reinterpret_cast<char*>(header.rep_), 8); }
friend std::ostream& operator<<(std::ostream& os, const icmp_header& header)
{ return os.write(reinterpret_cast<const char*>(header.rep_), 8); }
private:
unsigned short decode(int a, int b) const
{ return (rep_[a] << 8) + rep_[b]; }
void encode(int a, int b, unsigned short n)
{
rep_[a] = static_cast<unsigned char>(n >> 8);
rep_[b] = static_cast<unsigned char>(n & 0xFF);
}
unsigned char rep_[8];
};
template <typename Iterator>
void compute_checksum(icmp_header& header,
Iterator body_begin, Iterator body_end)
{
unsigned int sum = (header.type() << 8) + header.code()
+ header.identifier() + header.sequence_number();
Iterator body_iter = body_begin;
while (body_iter != body_end)
{
sum += (static_cast<unsigned char>(*body_iter++) << 8);
if (body_iter != body_end)
sum += static_cast<unsigned char>(*body_iter++);
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
header.checksum(static_cast<unsigned short>(~sum));
}
#endif // ICMP_HEADER_HPP
File so/ipv4_header.hpp
//
// ipv4_header.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef IPV4_HEADER_HPP
#define IPV4_HEADER_HPP
#include <algorithm>
#include <boost/asio/ip/address_v4.hpp>
// Packet header for IPv4.
//
// The wire format of an IPv4 header is:
//
// 0 8 16 31
// +-------+-------+---------------+------------------------------+ ---
// | | | | | ^
// |version|header | type of | total length in bytes | |
// | (4) | length| service | | |
// +-------+-------+---------------+-+-+-+------------------------+ |
// | | | | | | |
// | identification |0|D|M| fragment offset | |
// | | |F|F| | |
// +---------------+---------------+-+-+-+------------------------+ |
// | | | | |
// | time to live | protocol | header checksum | 20 bytes
// | | | | |
// +---------------+---------------+------------------------------+ |
// | | |
// | source IPv4 address | |
// | | |
// +--------------------------------------------------------------+ |
// | | |
// | destination IPv4 address | |
// | | v
// +--------------------------------------------------------------+ ---
// | | ^
// | | |
// / options (if any) / 0 - 40
// / / bytes
// | | |
// | | v
// +--------------------------------------------------------------+ ---
class ipv4_header
{
public:
ipv4_header() { std::fill(rep_, rep_ + sizeof(rep_), 0); }
unsigned char version() const { return (rep_[0] >> 4) & 0xF; }
unsigned short header_length() const { return (rep_[0] & 0xF) * 4; }
unsigned char type_of_service() const { return rep_[1]; }
unsigned short total_length() const { return decode(2, 3); }
unsigned short identification() const { return decode(4, 5); }
bool dont_fragment() const { return (rep_[6] & 0x40) != 0; }
bool more_fragments() const { return (rep_[6] & 0x20) != 0; }
unsigned short fragment_offset() const { return decode(6, 7) & 0x1FFF; }
unsigned int time_to_live() const { return rep_[8]; }
unsigned char protocol() const { return rep_[9]; }
unsigned short header_checksum() const { return decode(10, 11); }
boost::asio::ip::address_v4 source_address() const
{
boost::asio::ip::address_v4::bytes_type bytes
= { { rep_[12], rep_[13], rep_[14], rep_[15] } };
return boost::asio::ip::address_v4(bytes);
}
boost::asio::ip::address_v4 destination_address() const
{
boost::asio::ip::address_v4::bytes_type bytes
= { { rep_[16], rep_[17], rep_[18], rep_[19] } };
return boost::asio::ip::address_v4(bytes);
}
friend std::istream& operator>>(std::istream& is, ipv4_header& header)
{
is.read(reinterpret_cast<char*>(header.rep_), 20);
if (header.version() != 4)
is.setstate(std::ios::failbit);
std::streamsize options_length = header.header_length() - 20;
if (options_length < 0 || options_length > 40)
is.setstate(std::ios::failbit);
else
is.read(reinterpret_cast<char*>(header.rep_) + 20, options_length);
return is;
}
private:
unsigned short decode(int a, int b) const
{ return (rep_[a] << 8) + rep_[b]; }
unsigned char rep_[60];
};
#endif // IPV4_HEADER_HPP
File so/test.cpp
#include "icmp_header.hpp"
#include "ipv4_header.hpp"
#include <boost/asio.hpp>
#include <functional>
#include <iostream>
#include <istream>
#include <memory>
#include <ostream>
using boost::asio::deadline_timer;
using boost::asio::ip::icmp;
namespace posix_time = boost::posix_time;
class pinger : public std::enable_shared_from_this<pinger> {
public:
pinger(boost::asio::io_service& io_service, const char* destination)
: resolver_(io_service)
, socket_(io_service, icmp::v4())
, timer_(io_service)
, sequence_number_(0)
, num_replies_(0) {
icmp::resolver::query query(icmp::v4(), destination, "");
destination_ = *resolver_.resolve(query);
}
void init() {
start_send();
start_receive();
}
private:
void start_send() {
std::string body("\"Hello!\" from Asio ping.");
// Create an ICMP header for an echo request.
icmp_header echo_request;
echo_request.type(icmp_header::echo_request);
echo_request.code(0);
echo_request.identifier(get_identifier());
echo_request.sequence_number(++sequence_number_);
compute_checksum(echo_request, body.begin(), body.end());
// Encode the request packet.
boost::asio::streambuf request_buffer;
std::ostream os(&request_buffer);
os << echo_request << body;
// Send the request.
time_sent_ = posix_time::microsec_clock::universal_time();
boost::system::error_code error;
boost::asio::socket_base::message_flags flags{};
socket_.send_to(request_buffer.data(), destination_, flags, error);
if (error) {
std::cout << "send_to failed1:" << error.message() << std::endl;
std::cout << "send_to failed2:" << std::endl;
timer_.expires_at(time_sent_ + posix_time::seconds(1));
timer_.async_wait(
std::bind(&pinger::start_send, shared_from_this()));
} else {
// Wait up to five seconds for a reply.
num_replies_ = 0;
timer_.expires_at(time_sent_ + posix_time::seconds(5));
timer_.async_wait(
std::bind(&pinger::handle_timeout, shared_from_this()));
}
}
void handle_timeout() {
if (num_replies_ == 0)
std::cout << "Request timed out" << std::endl;
// Requests must be sent no less than one second apart.
timer_.expires_at(time_sent_ + posix_time::seconds(1));
timer_.async_wait(std::bind(&pinger::start_send, shared_from_this()));
}
void start_receive() {
// Discard any data already in the buffer.
reply_buffer_.consume(reply_buffer_.size());
// Wait for a reply. We prepare the buffer to receive up to 64KB.
socket_.async_receive(
reply_buffer_.prepare(65536),
std::bind(&pinger::handle_receive, shared_from_this(),
std::placeholders::_1, std::placeholders::_2));
}
void handle_receive(boost::system::error_code error, std::size_t length) {
// The actual number of bytes received is committed to the buffer so
// that we can extract it using a std::istream object.
if (error) {
std::cout << "error in handle_receive:"
<< boost::system::system_error(error).what() << std::endl;
}
reply_buffer_.commit(length);
// Decode the reply packet.
std::istream is(&reply_buffer_);
ipv4_header ipv4_hdr;
icmp_header icmp_hdr;
is >> ipv4_hdr >> icmp_hdr;
// We can receive all ICMP packets received by the host, so we need to
// filter out only the echo replies that match the our identifier and
// expected sequence number.
if (is && icmp_hdr.type() == icmp_header::echo_reply &&
icmp_hdr.identifier() == get_identifier() &&
icmp_hdr.sequence_number() == sequence_number_) {
// If this is the first reply, interrupt the five second timeout.
if (num_replies_++ == 0)
timer_.cancel();
// Print out some information about the reply packet.
posix_time::ptime now =
posix_time::microsec_clock::universal_time();
std::cout << length - ipv4_hdr.header_length() << " bytes from "
<< ipv4_hdr.source_address()
<< ": icmp_seq=" << icmp_hdr.sequence_number()
<< ", ttl=" << ipv4_hdr.time_to_live()
<< ", time=" << (now - time_sent_).total_milliseconds()
<< " ms" << std::endl;
}
start_receive();
}
static unsigned short get_identifier() {
#if defined(BOOST_WINDOWS)
return static_cast<unsigned short>(::GetCurrentProcessId());
#else
return static_cast<unsigned short>(::getpid());
#endif
}
icmp::resolver resolver_;
icmp::endpoint destination_;
icmp::socket socket_;
deadline_timer timer_;
unsigned short sequence_number_;
posix_time::ptime time_sent_;
boost::asio::streambuf reply_buffer_;
std::size_t num_replies_;
};
int main(int argc, char *argv[]) {
try {
if (argc != 2) {
std::cerr << "Usage: ping <host>" << std::endl;
return 1;
}
boost::asio::io_service io_service;
auto sp = std::make_shared<pinger>(io_service, argv[1]);
sp->init();
io_service.run();
} catch (std::exception &e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
}
Build:
docker build -t sopingtest
Run:
docker run --rm -it sopingtest
Demo
I am new to mmap and still learning it . Based on my understanding i have created class for mmap which will be used to map a file in memory . The entire class is working fine but problem is coming when destructor is called ..the problem is segmentation fault or invalid pointer error is coming at the end of main function ...I have posted code of my class and main function which is using that class ...
Map.h
class MapData
{
public :
MapData();
~MapData();
MapData(char []);
bool OPEN();
void fnClose();
long fnGetSize();
char * fnGetFileRef();
char * ReadNextData(int );
private :
char * ptrRecord;
char ptrFileNm[250+1];
int fd;
struct stat sbuf;
bool bSuccess;
long sTotalSize;
char acData[2000+1];
long lCurrRead;
};
MapData.cpp
MapData::MapData()
{
}
MapData::~MapData()
{
printf("Inside MADATA Destructor \n ");
}
MapData::MapData(char acInput[])
{
strcpy(ptrFileNm,acInput);
sTotalSize=0;
lCurrRead=0;
bSuccess=false;
}
bool MapData::OPEN()
{
// if failed return false flg
if ((fd = open(ptrFileNm, O_RDONLY)) == -1) {
return bSuccess;
}
if (stat(ptrFileNm, &sbuf) == -1) {
return bSuccess;
}
// copy in local variable
sTotalSize = sbuf.st_size;
ptrRecord = (char * )mmap( (caddr_t)0, sTotalSize, PROT_READ, MAP_SHARED, fd, 0) ;
if (ptrRecord == (char *)(caddr_t)(-1) ) {
perror("Fail to Map Data ");
return bSuccess;
}
else
{
printf("Successfully Map Data***[%ld] \n",sTotalSize);
bSuccess=true;
}
return bSuccess;
}
char * MapData::fnGetFileRef()
{
return ptrRecord;
}
char * MapData::ReadNextData(int iX)
{
if((lCurrRead+iX)<sTotalSize)
{
memset(acData,0x00,sizeof(acData));
strncpy(acData,ptrRecord+lCurrRead,iX);
acData[iX+1]='\0';
lCurrRead+=iX;
}else{
strcpy(acData,"ZZZ");
}
return acData;
}
long MapData::fnGetSize()
{
return sTotalSize;
}
void MapData::fnClose()
{
// Don't forget to free the mmapped memory
if(munmap(ptrRecord, sTotalSize) == -1)
{
close(fd);
perror("Error un-mmapping the file");
exit(EXIT_FAILURE);
}
// Un-mmaping doesn't close the file, so we still need to do that.
close(fd);
printf("CLOSED SUCCESSFULLY \n ");
}
Main.cpp
int main()
{
char acFileNm[500+1];
MEMSET(acFileNm); // clean the variable
// file name to be read
strcpy(acFileNm,"ABDFILE.txt");
long lProcCnt=0; // no of byte read by program
char acLine[MAX_LINE_LENGTH+1]; // hold current read line
bool bFlag=true; // main flag
DEBUG_PRINT("File to be processed:%s \n",acFileNm);
// create object of mmap
MapData * pt1 = NULL;
pt1 = new MapData(acFileNm);
if(!pt1)
{
cout<<"Error creating object so quit ..."<<endl;
return 0 ;
}
auto_ptr<MapData> ptrMap( pt1 ); // pass ownership to auto deletor to delete memory
DEBUG_PRINT("STEP1:%s \n","OBJECT CREATION FOR FILE MAPPED IN MEMORY");
// try to open the file
if(ptrMap->OPEN())
{
// on success..get pointer to first char of file
char * ptrData = ptrMap->fnGetFileRef();
long lCompSize=ptrMap->fnGetSize(); // total no of bytes = fiexed line size * no of row + (no of row * EOL)
short int iEOL=0;
// logic to identify file generated on ewhich OS
if( (*(ptrData+MAX_LINE_LENGTH) == '\r') && (*(ptrData+MAX_LINE_LENGTH+1) == '\n'))
{
// DOS format CRLF
iEOL = 2;
}else if(*(ptrData+MAX_LINE_LENGTH) == '\n'){
// Unix format LF
iEOL = 1;
}
DEBUG_PRINT("STEP2: SIZEOFFILE%ld FILESYSTEM FORMAT:%d \n",lCompSize,iEOL);
// here read till it reaches maximum limit of file
while(lProcCnt<lCompSize)
{
//DEBUG_PRINT("PROC COUNTER[%ld] MAX_COUNTER[%ld] \n",lProcCnt,lCompSize);
lProcCnt+=MAX_LINE_LENGTH+iEOL; // increement no of bytes read at initial
MEMSET(acLine);
strncpy(acLine,ptrData+lProcCnt,MAX_LINE_LENGTH); // read line
acLine[MAX_LINE_LENGTH+1]='\0';
// process the line :function is called here to process the line
}
}else{
DEBUG_PRINT("MAP DATA FAILED OF FILE[%s] \n",acFileNm);
bFlag=false;
}
// at the end check if all the controls are matched
if(bFlag)
DEBUG_PRINT("END OF FILE PROCESSING SUCCESS \n");
else
DEBUG_PRINT("END OF FILE PROCESSING FAILED \n");
// close the memory map
ptrMap->fnClose();
MapData * ptr5 = ptrMap.release(); // release the ownership
delete ptr5; **// segmentation fault comes here ...**
}
Please suggest me where i am going wrong since gdb is also not helping ...detailed explanation will be good for me to understand ...
Stacktrace generated by gdb:
*** glibc detected *** DemoMap: free(): invalid pointer: 0x0804c000 ***
======= Backtrace: =========
/lib/libc.so.6[0x9bbc81]
/lib/libc.so.6[0x9be562]
/usr/lib/libstdc++.so.6(_ZdlPv+0x22)[0x544552]
DemoMap[0x80491e6]
/lib/libc.so.6(__libc_start_main+0xe6)[0x961d36]
DemoMap[0x8048d91]
======= Memory map: ========
00110000-00111000 r-xp 00000000 00:00 0 [vdso]
0044c000-00469000 r-xp 00000000 08:03 1237 /lib/libgcc_s-4.4.7-20120601.so.1
00469000-0046a000 rw-p 0001d000 08:03 1237 /lib/libgcc_s-4.4.7-20120601.so.1
00495000-00576000 r-xp 00000000 08:02 132841 /usr/lib/libstdc++.so.6.0.13
00576000-0057a000 r--p 000e0000 08:02 132841 /usr/lib/libstdc++.so.6.0.13
0057a000-0057c000 rw-p 000e4000 08:02 132841 /usr/lib/libstdc++.so.6.0.13
0057c000-00582000 rw-p 00000000 00:00 0
00929000-00947000 r-xp 00000000 08:03 1065 /lib/ld-2.12.so
00947000-00948000 r--p 0001d000 08:03 1065 /lib/ld-2.12.so
00948000-00949000 rw-p 0001e000 08:03 1065 /lib/ld-2.12.so
0094b000-00adb000 r-xp 00000000 08:03 1067 /lib/libc-2.12.so
00adb000-00adc000 ---p 00190000 08:03 1067 /lib/libc-2.12.so
00adc000-00ade000 r--p 00190000 08:03 1067 /lib/libc-2.12.so
00ade000-00adf000 rw-p 00192000 08:03 1067 /lib/libc-2.12.so
00adf000-00ae2000 rw-p 00000000 00:00 0
00b29000-00b51000 r-xp 00000000 08:03 1211 /lib/libm-2.12.so
00b51000-00b52000 r--p 00027000 08:03 1211 /lib/libm-2.12.so
00b52000-00b53000 rw-p 00028000 08:03 1211 /lib/libm-2.12.so
08048000-0804b000 r-xp 00000000 08:08 2883976 DemoMap
0804b000-0804c000 rw-p 00002000 08:08 2883976 DemoMap
0804c000-0806d000 rw-p 00000000 00:00 0 [heap]
b7e00000-b7e21000 rw-p 00000000 00:00 0
b7e21000-b7f00000 ---p 00000000 00:00 0
b7f9b000-b7fe5000 r--s 00000000 08:08 4326707 ABCDEF.TXT
b7fe5000-b7fe8000 rw-p 00000000 00:00 0
b7ffd000-b8000000 rw-p 00000000 00:00 0
bffeb000-c0000000 rw-p 00000000 00:00 0 [stack]
may be here.
char ptrFileNm[250+1];
char acFileNm[500+1];
MapData::MapData(char acInput[])
{
strcpy(ptrFileNm,acInput);//segmentation fault
sTotalSize=0;
lCurrRead=0;
bSuccess=false;
}
As stated on the topic, i'm using objcopy to load SDL_Image images with MinGW over Eclipse Helios for windows.
I'm using the command: objcopy --input-target binary --output-target pei-i386 --binary-architecture i386 Lilothyn.jpg Lilothyn.o
That results in the file:
Lilothyn.o: file format pei-i386
Lilothyn.o
architecture: i386, flags 0x00000030:
HAS_SYMS, HAS_LOCALS
start address 0x00000000
Characteristics 0x305
relocations stripped
line numbers stripped
32 bit words
debugging information removed
Time/Date Thu Jan 01 00:00:00 1970
Magic 0000
MajorLinkerVersion 0
MinorLinkerVersion 0
SizeOfCode 00000000
SizeOfInitializedData 00000000
SizeOfUninitializedData 00000000
AddressOfEntryPoint 00000000
BaseOfCode 00000000
BaseOfData 00000000
ImageBase 00000000
SectionAlignment 00000000
FileAlignment 00000000
MajorOSystemVersion 0
MinorOSystemVersion 0
MajorImageVersion 0
MinorImageVersion 0
MajorSubsystemVersion 0
MinorSubsystemVersion 0
Win32Version 00000000
SizeOfImage 00000000
SizeOfHeaders 00000000
CheckSum 00000000
Subsystem 00000000 (unspecified)
DllCharacteristics 00000000
SizeOfStackReserve 00000000
SizeOfStackCommit 00000000
SizeOfHeapReserve 00000000
SizeOfHeapCommit 00000000
LoaderFlags 00000000
NumberOfRvaAndSizes 00000000
The Data Directory
Entry 0 00000000 00000000 Export Directory [.edata (or where ever we found it)]
Entry 1 00000000 00000000 Import Directory [parts of .idata]
Entry 2 00000000 00000000 Resource Directory [.rsrc]
Entry 3 00000000 00000000 Exception Directory [.pdata]
Entry 4 00000000 00000000 Security Directory
Entry 5 00000000 00000000 Base Relocation Directory [.reloc]
Entry 6 00000000 00000000 Debug Directory
Entry 7 00000000 00000000 Description Directory
Entry 8 00000000 00000000 Special Directory
Entry 9 00000000 00000000 Thread Storage Directory [.tls]
Entry a 00000000 00000000 Load Configuration Directory
Entry b 00000000 00000000 Bound Import Directory
Entry c 00000000 00000000 Import Address Table Directory
Entry d 00000000 00000000 Delay Import Directory
Entry e 00000000 00000000 CLR Runtime Header
Entry f 00000000 00000000 Reserved
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 000024fb 00000000 00000000 000000c0 2**0
CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
[ 0](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 _binary_Lilothyn_jpg_start
[ 1](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x000024fb _binary_Lilothyn_jpg_end
[ 2](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x000024fb _binary_Lilothyn_jpg_size
... and the other:
Tommy.o: file format pei-i386
Tommy.o
architecture: i386, flags 0x00000030:
HAS_SYMS, HAS_LOCALS
start address 0x00000000
Characteristics 0x305
relocations stripped
line numbers stripped
32 bit words
debugging information removed
Time/Date Thu Jan 01 00:00:00 1970
Magic 0000
MajorLinkerVersion 0
MinorLinkerVersion 0
SizeOfCode 00000000
SizeOfInitializedData 00000000
SizeOfUninitializedData 00000000
AddressOfEntryPoint 00000000
BaseOfCode 00000000
BaseOfData 00000000
ImageBase 00000000
SectionAlignment 00000000
FileAlignment 00000000
MajorOSystemVersion 0
MinorOSystemVersion 0
MajorImageVersion 0
MinorImageVersion 0
MajorSubsystemVersion 0
MinorSubsystemVersion 0
Win32Version 00000000
SizeOfImage 00000000
SizeOfHeaders 00000000
CheckSum 00000000
Subsystem 00000000 (unspecified)
DllCharacteristics 00000000
SizeOfStackReserve 00000000
SizeOfStackCommit 00000000
SizeOfHeapReserve 00000000
SizeOfHeapCommit 00000000
LoaderFlags 00000000
NumberOfRvaAndSizes 00000000
The Data Directory
Entry 0 00000000 00000000 Export Directory [.edata (or where ever we found it)]
Entry 1 00000000 00000000 Import Directory [parts of .idata]
Entry 2 00000000 00000000 Resource Directory [.rsrc]
Entry 3 00000000 00000000 Exception Directory [.pdata]
Entry 4 00000000 00000000 Security Directory
Entry 5 00000000 00000000 Base Relocation Directory [.reloc]
Entry 6 00000000 00000000 Debug Directory
Entry 7 00000000 00000000 Description Directory
Entry 8 00000000 00000000 Special Directory
Entry 9 00000000 00000000 Thread Storage Directory [.tls]
Entry a 00000000 00000000 Load Configuration Directory
Entry b 00000000 00000000 Bound Import Directory
Entry c 00000000 00000000 Import Address Table Directory
Entry d 00000000 00000000 Delay Import Directory
Entry e 00000000 00000000 CLR Runtime Header
Entry f 00000000 00000000 Reserved
Sections:
Idx Name Size VMA LMA File off Algn
0 .data 000834fe 00000000 00000000 000000c0 2**0
CONTENTS, ALLOC, LOAD, DATA
SYMBOL TABLE:
[ 0](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 _binary_Tommy_jpg_start
[ 1](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x000834fe _binary_Tommy_jpg_end
[ 2](sec -1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x000834fe _binary_Tommy_jpg_size
The problem is that this last file (Tommy.o) loads properly, while the 1st file (Lilothyn.o) doesn't. As you can see the two are seemingly similar.
My code is extensive so i'll post the relevant parts only.
Source.cpp:
int displayFillThread(SDL_Renderer *renderer, SDL_Window *window, bool *_end) throw()
{
std::cout << "Thread initializing..." << std::endl;
SDL_Texture *texture = getTextureFromStream(&binary_Lilothyn_jpg_start, binary_Lilothyn_jpg_size, window, renderer);
if (texture == NULL)
{
std::cout << "Thread: Failed to load image - " << SDL_GetError() << std::endl;
return 1;
}
std::cout << "Thread initialized!" << std::endl;
for(int i= 10; !*_end && i < 400; i+= 100)
for(int j= 10; !*_end && j < 400; j+= 100)
{
SDL_Delay(100);
AddTextureToRederer(renderer, texture, i, j, 100, 100);
SDL_RenderPresent(renderer);
}
return 0;
}
SDL_Texture *getTextureFromStream(char binary[], unsigned int binary_size, SDL_Window *window, SDL_Renderer *renderer) throw()
{
std::cout << "Starting getTextureFromJPEGStream!" << std::endl;
// char* st = loadFileObject(binary_start, binary_end);
SDL_RWops *rw = SDL_RWFromConstMem(binary, binary_size);
std::cout << "rw loaded!" << std::endl;
SDL_Surface *tmpSurf = IMG_Load_RW(rw, 0);
//SDL_Surface *tmpSurf = SDL_CreateRGBSurfaceFrom(Lilothyn_jpg, 123, 102, 24, 96, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
if (tmpSurf != NULL)
{
SDL_Surface *surf = SDL_ConvertSurfaceFormat(tmpSurf, SDL_GetWindowPixelFormat(window), 0);
if (surf != NULL)
{
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surf);
SDL_FreeSurface(surf);
std::cout << "tmpSurf loaded!" << std::endl;
return texture;
}//*/
// SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, tmpSurf);
SDL_FreeSurface(tmpSurf);
std::cout << "surf load failed!" << std::endl;
return NULL;
}
std::cout << "tmpSurf load failed!" << std::endl;
return NULL;
}
int main(int argc, char** argv)
{
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
std::cout << "SDL init Error: " << SDL_GetError() << std::endl;
exit(1);
}
SDL_Window *window = SDL_CreateWindow("SDL_Test", 0, 0, _SCREEN_WIDTH_, _SCREEN_HEIGHT_, SDL_WINDOW_OPENGL | SDL_RENDERER_ACCELERATED); // SDL_WINDOW_FULLSCREEN |
if (window == NULL)
{
std::cout << "Window init Error: " << SDL_GetError() << std::endl;
exit(1);
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
if (renderer == NULL)
{
SDL_ShowSimpleMessageBox(0, "Renderer init error", SDL_GetError(), window);
}
//SDL_Texture *texture = getTextureFromJPEGStream(binary_Tommy_jpg_start, binary_Tommy_jpg_end, binary_Tommy_jpg_size, window, renderer);
SDL_Texture *texture = getTextureFromStream(&binary_Tommy_jpg_start, binary_Tommy_jpg_size, window, renderer);
//getTextureFromImage("Resources/Tommy.jpg", window, renderer);
if (texture == NULL)
{
SDL_ShowSimpleMessageBox(0, "Background Texture init error", SDL_GetError(), window);
return 1;
}
SDL_RenderCopy(renderer, texture, NULL, NULL);
//AddTextureToRederer(renderer, FTex, 10, 10, 100, 100);
SDL_RenderPresent(renderer);
SDL_Event event;
bool _end = false;
std::cout << "Starting Thread!" << std::endl;
std::thread thread1;
try
{
thread1 = std::thread(displayFillThread, renderer, window, &_end);
std::cout << "Thread loaded!" << std::endl;
}
catch(std::exception& e)
{
std::cout << "Thread load failed: " << e.what() << std::endl;
return 1;
}
std::cout << "main while starting!" << std::endl;
while(!_end)
{
//...
Source.h:
#ifndef SOURCE_H_
#define SOURCE_H_
static int _SCREEN_WIDTH_ = 1024;
static int _SCREEN_HEIGHT_ = 800;
extern char binary_Tommy_jpg_start;
extern unsigned int binary_Tommy_jpg_size;
extern char binary_Lilothyn_jpg_start;
extern unsigned int binary_Lilothyn_jpg_size;
int displayFillThread(SDL_Renderer *renderer, SDL_Window *window, bool *_end) throw();
SDL_Texture *getTextureFromStream(char binary[], unsigned int binary_size, SDL_Window *window, SDL_Renderer *renderer) throw();
//...
And the output:
Starting getTextureFromJPEGStream!
rw loaded!
tmpSurf loaded!
Starting Thread!
Thread loaded!
Thread initializing...
main while starting!
Note that it didn't write the second "getTextureFromJPEGStream!" neither did it appear to have thrown an exception.
It compiles with no problems whatsoever so, is it possible that the Lilothyn.o file is being created corrupted? (I have rebuilt it more than once) And/or maybe the linker isn't linking correctly?
While executing, the program simple stops responding after loading the 1st image, while trying to load the 2nd.
Thank you for the replies.
I've solved this now, the problem was the types used on the .o file.
New code is as follows.
Source.h:
extern uint8_t binary_Lilothyn_jpg_start[];
extern uint8_t binary_Lilothyn_jpg_size[];
Source.cpp
SDL_Texture *getTextureFromStream(uint8_t binary[], uint8_t binary_size[], SDL_Window *window, SDL_Renderer *renderer) throw()
{
size_t converted_size = (size_t)((void *)binary_size);
SDL_Surface *tmpSurf = IMG_Load_RW(SDL_RWFromConstMem(binary, converted_size), 0);
if (tmpSurf != NULL)
{
//...
Thanks to all the viewers, I hope this helps!
i have the following main code:
#include "ComHandler.h"
#include "socketMessage.h"
#define THIS_IP "localhost"
#define C_PORT 32456
#define S_PORT 25465
#define S_PORT_UDP 22548
int main(int argc, char* argv[]) {
conOptions opts;
strncpy(opts.password, "PASS", sizeof("PASS"));
opts.retryQty = 5;
opts.timeout = 300;
char dir[INET6_ADDRSTRLEN];
strncpy(dir, THIS_IP, sizeof(THIS_IP));
if (argv[1][0] == 'C') {
opts.connType = CLIENT_HANDLER;
opts.thisID = 2;
ComHandler comH(opts);
char buffer[10];
strncpy(buffer, "Testing", 10);
int rtnValue = comH.sendMsg(buffer, 10, 1, TCP_C);
std::cout << "Returned Value: " << rtnValue << std::endl;
} else {
opts.connType = SERVER_HANDLER;
opts.thisID = 1;
ComHandler comH(opts);
comH.addConnectionData(2, dir, C_PORT);
comH.addConnectionData(comH.getID(), dir, S_PORT);
char rcvdTxt[MINIDATA_DATA_SIZE];
comH.receiveMsg(rcvdTxt, MINIDATA_DATA_SIZE, 2, TCP_C);
std::cout << "Received: " << rcvdTxt << std::endl;
comH.closeCommunications();
}
}
The code is for testing my communication platform. The platform works well, but the problem appears when the messages are received by the Handler (ComHandler). When i call the method "receiveMsg" from ComHandler, i get a "stack smashing detected" in the "return" of the method.
This is the "ComHandler" class:
#ifndef COMHANDLER_H_
#define COMHANDLER_H_
#include "Constants.h"
#include "ComConstants.h"
#include "DataLogger.h"
#include <list>
#include <math.h>
#define CLIENT_HANDLER 1
#define SERVER_HANDLER 2
#define COMMENT_LINE '#'
#define TXT_SEPARATOR ';'
#define MINIDATA_DATA_SIZE (COMDATA_MAX_SIZE - 4* sizeof(int))
enum CON_TYPE {
TCP_C, UDP_C
};
#pragma pack(push)
#pragma pack(1)
typedef struct {
int totalPackets;
int sequenceNumber;
int sequenceID;
int dataSize;
char data[MINIDATA_DATA_SIZE];
} miniData;
#pragma pack(pop)
typedef struct connectionOptions {
unsigned int timeout;
unsigned int retryQty;
id_t thisID;
char password[PASSWORD_MAX_SIZE];
int connType;
connectionOptions() :
timeout(CON_TIMEOUT), retryQty(SOCKET_RETRIES), connType(
SERVER_HANDLER) {
memset(password, 0, PASSWORD_MAX_SIZE);
}
connectionOptions(connectionOptions& opt) {
timeout = opt.timeout;
retryQty = opt.retryQty;
thisID = opt.thisID;
connType = opt.connType;
memcpy(password, opt.password, PASSWORD_MAX_SIZE);
}
} conOptions;
class ComHandler {
private:
int dataForwarder_ReceiverMsgQueue;
int dataForwarder_SenderMsgQueue;
conOptions opts;
int sequenceID;
Semaphore ch_mux;
SharedMemory<comHandlerGlOp> ch_shm;
void cpyMiniData(miniData* to, miniData* from);
void createIPCs();
public:
ComHandler();
ComHandler(conOptions options);
ComHandler(id_t thisID);
virtual ~ComHandler();
int receiveMsg(char* buffer, int bufferSize, id_t originID,
CON_TYPE type = TCP_C);
int sendMsg(char* buffer, std::size_t bufferSize, id_t destinationID,
CON_TYPE type = TCP_C);
void configListenersData(char addr[INET6_ADDRSTRLEN], int port,
CON_TYPE type);
void addConnectionData(id_t id, char addr[INET6_ADDRSTRLEN], int port);
void addConnectionData(const char* file);
void modifyConnectionData(id_t id, char addr[INET6_ADDRSTRLEN], int port);
void removeConnectionData(id_t id);
int getID();
void closeCommunications();
};
#endif /* COMHANDLER_H_ */
The comData structure:
typedef struct {
long type;
int requestType;
char destination[INET6_ADDRSTRLEN];
char origin[INET6_ADDRSTRLEN];
id_t originID;
id_t destinationID;
int port;
pid_t senderPid;
pid_t originPid;
char data[COMDATA_MAX_SIZE];
} comData;
And the method with the problem:
int ComHandler::receiveMsg(char* buffer, int bufferSize, id_t originID,
CON_TYPE type) {
comData aux;
aux.type = DATA_RECEIVE;
int qtyReceived = 0;
if (originID != ANY_MSG_ORIGIN) {
if (type == TCP_C)
aux.requestType = RECEIVE_DATA_FROM_DESTINATION_TCP;
else
aux.requestType = RECEIVE_DATA_FROM_DESTINATION_UDP;
} else {
if (type == TCP_C)
aux.requestType = RECEIVE_ANY_DATA_TCP;
else
aux.requestType = RECEIVE_ANY_DATA_UDP;
}
aux.originID = originID;
aux.senderPid = getpid();
aux.originPid = getpid();
msgsnd(dataForwarder_ReceiverMsgQueue, &aux, sizeof(comData), 0);
msgrcv(dataForwarder_ReceiverMsgQueue, &aux, sizeof(comData), getpid(), 0);
/* More Code */
return qtyReceived;
}
The stack smashing error appears after "return qtyReceived;" is called. And the /* More Code */ in the middle is the non important code, because if a delete that part, the stack smashing stills appears.
After much debugging i found that the smashing appears if i call:
`msgrcv(dataForwarder_ReceiverMsgQueue, &aux, sizeof(comData), getpid(), 0);`
if i comment that line, i don't get the error.
Also with the debugger, i was able to see that the messages from the queue arrive with good format and size, exactly as they should.
The console output is:
*** stack smashing detected ***: /media/blackhole/workspace/Final/bin/ComTest terminated
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x45)[0xb7df88d5]
/lib/i386-linux-gnu/libc.so.6(+0xe7887)[0xb7df8887]
/media/blackhole/workspace/Final/bin/ComTest[0x804dc6b]
/media/blackhole/workspace/Final/bin/ComTest[0x804a002]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb7d2a113]
/media/blackhole/workspace/Final/bin/ComTest[0x8049d11]
======= Memory map: ========
08048000-08054000 r-xp 00000000 08:05 256373 /media/blackhole/workspace/Final/bin/ComTest
08054000-08055000 r--p 0000b000 08:05 256373 /media/blackhole/workspace/Final/bin/ComTest
08055000-08056000 rw-p 0000c000 08:05 256373 /media/blackhole/workspace/Final/bin/ComTest
08056000-08077000 rw-p 00000000 00:00 0 [heap]
b7d0f000-b7d11000 rw-p 00000000 00:00 0
b7d11000-b7e87000 r-xp 00000000 08:06 525221 /lib/i386-linux-gnu/libc-2.13.so
b7e87000-b7e89000 r--p 00176000 08:06 525221 /lib/i386-linux-gnu/libc-2.13.so
b7e89000-b7e8a000 rw-p 00178000 08:06 525221 /lib/i386-linux-gnu/libc-2.13.so
b7e8a000-b7e8d000 rw-p 00000000 00:00 0
b7e8d000-b7ea9000 r-xp 00000000 08:06 525242 /lib/i386-linux-gnu/libgcc_s.so.1
b7ea9000-b7eaa000 r--p 0001b000 08:06 525242 /lib/i386-linux-gnu/libgcc_s.so.1
b7eaa000-b7eab000 rw-p 0001c000 08:06 525242 /lib/i386-linux-gnu/libgcc_s.so.1
b7eab000-b7eac000 rw-p 00000000 00:00 0
b7eac000-b7ed4000 r-xp 00000000 08:06 525251 /lib/i386-linux-gnu/libm-2.13.so
b7ed4000-b7ed5000 r--p 00028000 08:06 525251 /lib/i386-linux-gnu/libm-2.13.so
b7ed5000-b7ed6000 rw-p 00029000 08:06 525251 /lib/i386-linux-gnu/libm-2.13.so
b7ed6000-b7fb4000 r-xp 00000000 08:06 5514 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7fb4000-b7fb5000 ---p 000de000 08:06 5514 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7fb5000-b7fb9000 r--p 000de000 08:06 5514 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7fb9000-b7fba000 rw-p 000e2000 08:06 5514 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.16
b7fba000-b7fc1000 rw-p 00000000 00:00 0
b7fdc000-b7fdd000 rw-s 00000000 00:04 163119127 /SYSV02056f32 (deleted)
b7fdd000-b7fdf000 rw-p 00000000 00:00 0
b7fdf000-b7fe0000 r-xp 00000000 00:00 0 [vdso]
b7fe0000-b7ffe000 r-xp 00000000 08:06 525208 /lib/i386-linux-gnu/ld-2.13.so
b7ffe000-b7fff000 r--p 0001d000 08:06 525208 /lib/i386-linux-gnu/ld-2.13.so
b7fff000-b8000000 rw-p 0001e000 08:06 525208 /lib/i386-linux-gnu/ld-2.13.so
bffdf000-c0000000 rw-p 00000000 00:00 0 [stack]
So, any ideas? If you need something about the code, just ask me.
According to this, the msgsz parameter of msgrcv() should be the size of the mtext member of the mymsg struct:
struct mymsg {
long int mtype; /* message type */
char mtext[1]; /* message text */
}
The problem is that you include the size of the mtype member (4 bytes) so msgrcv() writes four bytes past the end of your struct which trashes the stack.