direct-code-execution / ns-3-dce

Run real programs in the discrete time simulator ns3
http://www.nsnam.org/projects/direct-code-execution/
75 stars 46 forks source link

SIGSEV with memset #113

Closed stoza closed 3 years ago

stoza commented 3 years ago

Description of the problem

I'm currently trying to use ns3 to run some simulation on IS-IS daemon of Frrouting which is a fork of guagga. But Every time I try to run the simulation I have a SIGSEV

[ 12/415] Creating build/lib/pkgconfig/libns3-dev-netlink-debug.pc
[118/415] Creating build/lib/pkgconfig/libns3-dev-dce-debug.pc
[121/415] Creating build/myscripts/ns-3-dce-quagga/lib/pkgconfig/libns3-dev-dce-quagga-debug.pc
[144/415] Creating build/myscripts/ns-3-dce-umip/lib/pkgconfig/libns3-dev-dce-umip-debug.pc
Waf: Leaving directory `/home/ns3dce/dce-linux-dev/source/ns-3-dce/build'
Build commands will be stored in build/compile_commands.json
'build' finished successfully (0.364s)
Command ['/home/ns3dce/dce-linux-dev/source/ns-3-dce/build/myscripts/test-isisd/bin/dce-test-isisd'] terminated with signal SIGSEGV. Run it under a debugger to get more information (./waf --run <program> --command-template="gdb --args %s <args>").

So after some research it appear that the line which cause the SIGSEV is the following: gid_t groups[NGROUPS_MAX] = {}; with NGROUPS_MAX=65536 And that's memset which cause the SIGSEV. Here you have the output of gdb:

gdb$ c
Continuing.
[New Thread 0x7ffff7ff4700 (LWP 190)]

Thread 2 "dce-test-isisd" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff7ff4700 (LWP 190)]
memset () at ../sysdeps/x86_64/memset.S:93
93  ../sysdeps/x86_64/memset.S: No such file or directory.
gdb$ bt
#0  memset () at ../sysdeps/x86_64/memset.S:93
#1  0x00007fffefb354bb in memset () at ../model/libc-ns3.h:129
#2  0x00007fffee587b71 in zprivs_init (zprivs=0x7fffee511000 <isisd_privs>) at lib/privs.c:592
#3  0x00007fffee56d8d5 in frr_init () at lib/libfrr.c:694
#4  0x00007fffee26c48f in main (argc=0x1, argv=0x7372f0, envp=<optimized out>) at isisd/isis_main.c:238
#5  0x00007ffff7a34f8d in ns3::DceManager::DoStartProcess (context=0x73a510) at ../model/dce-manager.cc:299
#6  0x00007ffff7ac3422 in ns3::TaskManager::Trampoline (context=0x739ab0) at ../model/task-manager.cc:275
#7  0x00007ffff7abf2d8 in ns3::PthreadFiberManager::Run (arg=0x73a810) at ../model/pthread-fiber-manager.cc:402
#8  0x00007ffff0363184 in start_thread (arg=0x7ffff7ff4700) at pthread_create.c:312
#9  0x00007ffff008fffd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:111
gdb$

And here you have a part of the output of valgrind:

==689== Memcheck, a memory error detector
==689== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==689== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==689== Command: /home/ns3dce/dce-linux-dev/source/ns-3-dce/build/myscripts/test-isisd/bin/dce-test-isisd
==689== 
==689== 
==689== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==689==  Access not within mapped region at address 0x3FE9B48
==689==    at 0xED72414: zprivs_init (privs.c:592)
==689==  If you believe this happened as a result of a stack
==689==  overflow in your program's main thread (unlikely but
==689==  possible), you can try to increase the size of the
==689==  main thread stack using the --main-stacksize= flag.
==689==  The main thread stack size used in this run was 8388608.
==689== Use of uninitialised value of size 8

So I've try a super simple code which use memset to initialize a big array:

#include<stdlib.h>
#include<stdio.h>

int main(int argc, char **argv){
        int arr[65536] = {};
        return 0;
}

And I've got exactly the same behavior. But when trying with a much smaller array (size=6) there is no problems.

output of ./waf configure

Setting top to                           : /home/ns3dce/dce-linux-dev/source/ns-3-dce 
Setting out to                           : /home/ns3dce/dce-linux-dev/source/ns-3-dce/build 
Checking for 'gcc' (C compiler)          : /usr/lib/ccache/gcc 
Checking for cc version                  : 4.9.4 
Checking for 'g++' (C++ compiler)        : /usr/lib/ccache/g++ 
Checking for program 'pkg-config'        : /usr/bin/pkg-config 
Checking for pkg-config version >= '0.0.0' : yes 
Checking for -Wl,--soname=foo              : yes

Steps to reproduce

To reproduce just compile the example code given above (and called memset_example in the following) with gcc: gcc -Wall -fPIC -g -pie -rdynamic -o memset_example memset_example.c. Then use the executable in a very simple scenario:

#include "ns3/network-module.h"
#include "ns3/core-module.h"
#include "ns3/internet-module.h"
#include "ns3/dce-module.h"
#include "ns3/quagga-helper.h"

using namespace ns3;

int main (int argc, char *argv[])
{
  CommandLine cmd;
  cmd.Parse (argc, argv);

  NodeContainer nodes;
  nodes.Create (1);

  InternetStackHelper stack;
  stack.Install (nodes);

  DceManagerHelper dceManager;
  dceManager.Install (nodes);

  DceApplicationHelper dce;
  ApplicationContainer apps;

  dce.SetBinary ("memset_example");
  dce.ResetArguments ();
  apps = dce.Install (nodes.Get (0));
  apps.Start (Seconds (4.0));

  Simulator::Stop (Seconds (1000100.0));
  Simulator::Run ();
  Simulator::Destroy ();

  return 0;
}

Then you should be able to have the SIGSEV.

Thanks a lot for your help

mas2tg commented 3 years ago

I haven't had time to reproduce your problem, but by looking quickly at your code, aren't you missing the following snippet in the simulation code? This would explain the memory access error.

dce.SetStackSize (1 << 20);
stoza commented 3 years ago

Oh yes that's was totally that! thank you!