Hugonweb | GDB LArSoft Tutorial

For this example, I made this analyzer:

////////////////////////////////////////////////////////////////////////
// Class:       GDBTest
// Plugin Type: analyzer (art v2_09_06)
// File:        GDBTest_module.cc
//
// Generated at Tue May  8 18:41:01 2018 by Justin Hugon using cetskelgen
// from cetlib version v3_01_03.
////////////////////////////////////////////////////////////////////////

#include "art/Framework/Core/EDAnalyzer.h"
#include "art/Framework/Core/ModuleMacros.h"
#include "art/Framework/Principal/Event.h"
#include "art/Framework/Principal/Handle.h"
#include "art/Framework/Principal/Run.h"
#include "art/Framework/Principal/SubRun.h"
#include "canvas/Utilities/InputTag.h"
#include "fhiclcpp/ParameterSet.h"
#include "messagefacility/MessageLogger/MessageLogger.h"

namespace test {
  class GDBTest;
}


class test::GDBTest : public art::EDAnalyzer {
public:
  explicit GDBTest(fhicl::ParameterSet const & p);
  // The compiler-generated destructor is fine for non-base
  // classes without bare pointers or other resource use.

  // Plugins should not be copied or assigned.
  GDBTest(GDBTest const &) = delete;
  GDBTest(GDBTest &&) = delete;
  GDBTest & operator = (GDBTest const &) = delete;
  GDBTest & operator = (GDBTest &&) = delete;

  // Required functions.
  void analyze(art::Event const & e) override;

private:

  // Declare member data here.

};


test::GDBTest::GDBTest(fhicl::ParameterSet const & p)
  :
  EDAnalyzer(p)  // ,
 // More initializers here.
{}

void test::GDBTest::analyze(art::Event const & e)
{
  // Implementation of required member function here.
  int x[10];
  for (size_t i=0; i < 2000; i++)
  {
    x[i*10000] = i;
  }

  mf::LogInfo("GDBTest") << "x[-9999999]: " << x[-99999999];
}

DEFINE_ART_MODULE(test::GDBTest)

Now suppose I run it like this:

lar -c gdbTest.fcl -S /dune/app/users/jhugon/tutorial/dunetpc_v06_69_00/fullpathnames_mcc10_protodune_beam_p2GeV_cosmics_3ms_sce_mcc10.0.txt

it should then segfault:

...
...
...
08-May-2018 19:06:11 CDT  Initiating request to open input file "/pnfs/dune/tape_backed/dunepro/mcc10/mc/full-reconstructed/02/04/91/93/mcc10_protodune_beam_p2GeV_cosmics_3ms_sce_35_20171229T035711_merged0.root"
08-May-2018 19:06:11 CDT  Opened input file "/pnfs/dune/tape_backed/dunepro/mcc10/mc/full-reconstructed/02/04/91/93/mcc10_protodune_beam_p2GeV_cosmics_3ms_sce_35_20171229T035711_merged0.root"
Begin processing the 1st record. run: 1 subRun: 87 event: 858 at 08-May-2018 19:06:14 CDT
Segmentation fault

Now, GDB can help us find what caused the segfault. First startup GDB with the lar executable:

gdb lar

and now within GDB, you would run your program with:

run -c gdbTest.fcl -S /dune/app/users/jhugon/tutorial/dunetpc_v06_69_00/fullpathnames_mcc10_protodune_beam_p2GeV_cosmics_3ms_sce_mcc10.0.txt

Now, the output looks like:

...
...
...
08-May-2018 19:12:54 CDT  Initiating request to open input file "/pnfs/dune/tape_backed/dunepro/mcc10/mc/full-reconstructed/02/04/91/93/mcc10_protodune_beam_p2GeV_cosmics_3ms_sce_35_20171229T035711_merged0.root"
08-May-2018 19:12:57 CDT  Opened input file "/pnfs/dune/tape_backed/dunepro/mcc10/mc/full-reconstructed/02/04/91/93/mcc10_protodune_beam_p2GeV_cosmics_3ms_sce_35_20171229T035711_merged0.root"
Begin processing the 1st record. run: 1 subRun: 87 event: 858 at 08-May-2018 19:13:00 CDT

Program received signal SIGSEGV, Segmentation fault.
0x00007fffe31e5f39 in test::GDBTest::analyze(art::Event const&) () at /nashome/j/jhugon/myduneapp/tutorial/dunetpc_v06_69_00/srcs/dunetpc/dune/Tutorial/GDBTest_module.cc:59
59      x[i*10000] = i;
Missing separate debuginfos, use: debuginfo-install cyrus-sasl-lib-2.1.23-15.el6_6.2.x86_64 freetype-2.3.11-15.el6_6.1.x86_64 glibc-2.12-1.209.el6_9.2.x86_64 keyutils-libs-1.4-5.el6.x86_64 krb5-libs-1.10.3-42z1.el6_7.x86_64 libcom_err-1.41.12-22.el6.x86_64 libcurl-7.19.7-53.el6_9.x86_64 libidn-1.18-2.el6.x86_64 libselinux-2.0.94-5.8.el6.x86_64 libssh2-1.4.2-2.el6_7.1.x86_64 ncurses-libs-5.7-4.20090207.el6.x86_64 nspr-4.13.1-1.el6.x86_64 nss-3.28.4-4.el6_9.x86_64 nss-softokn-freebl-3.14.3-23.el6_7.x86_64 nss-util-3.28.4-1.el6_9.x86_64 openldap-2.4.40-6.el6_7.x86_64 openssl-1.0.1e-48.sl6_8.4.x86_64 pcre-7.8-7.el6.x86_64 xz-libs-4.999.9-0.5.beta.20091007git.el6.x86_64 zlib-1.2.3-29.el6.x86_64
(gdb) 

So, it tells you that a Segmentation fault happened, and then told you where it happened--on line 59 of GDBTest_module.cc. We are also still in GDB so can debug further. This is much more helpful than without GDB. Don\'t worry about the Missing separate debuginfos..., that just means that those libraries don\'t have debugging info, so you won\'t be able to debug code inside of them.

The backtrace command, bt, will show you the list of functions called to get to where the program execution is now all the way up to the main() function. Mine looks like this:

(gdb) bt
#0  0x00007fffe31e5f39 in test::GDBTest::analyze(art::Event const&) () at /nashome/j/jhugon/myduneapp/tutorial/dunetpc_v06_69_00/srcs/dunetpc/dune/Tutorial/GDBTest_module.cc:59
#1  0x00007ffff6453222 in art::EDAnalyzer::doEvent () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/Core/EDAnalyzer.cc:29
#2  0x00007fffe31e95b5 in art::WorkerT<art::EDAnalyzer>::implDoProcess () at /cvmfs/larsoft.opensciencegrid.org/products/art/v2_09_06/include/art/Framework/Core/WorkerT.h:88
#3  0x00007ffff7284d9f in bool art::Worker::ImplDoWork<(art::BranchActionType)2>::invoke<art::EventPrincipal>(art::Worker*, art::EventPrincipal&, art::CurrentProcessingContext const*) () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/Principal/Worker.h:200
#4  0x00007ffff727b479 in bool art::Worker::doWork<art::ProcessPackage<(art::Level)4> >(art::ProcessPackage<(art::Level)4>::MyPrincipal&, art::CurrentProcessingContext const*) () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/Principal/Worker.h:258
#5  0x00007ffff7284f56 in bool art::WorkerInPath::runWorker<art::ProcessPackage<(art::Level)4> >(art::ProcessPackage<(art::Level)4>::MyPrincipal&, art::CurrentProcessingContext const*) () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/Core/WorkerInPath.h:107
#6  0x00007ffff727c373 in void art::Path::process<art::ProcessPackage<(art::Level)4> >(art::ProcessPackage<(art::Level)4>::MyPrincipal&) () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/Core/Path.h:148
#7  0x00007ffff726a181 in void art::EndPathExecutor::process<art::ProcessPackage<(art::Level)4> >(art::ProcessPackage<(art::Level)4>::MyPrincipal&) () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/Core/EndPathExecutor.h:127
#8  0x00007ffff725cf82 in void art::EventProcessor::process_<art::ProcessPackage<(art::Level)4> >(art::ProcessPackage<(art::Level)4>::MyPrincipal&) () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/EventProcessor.h:204
#9  0x00007ffff724c9dc in art::EventProcessor::processEvent() () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/EventProcessor.cc:880
#10 0x00007ffff7249ccf in void art::EventProcessor::process<(art::Level)4>() () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/EventProcessor.cc:421
#11 0x00007ffff7283455 in void art::EventProcessor::process<(art::Level)3>()::{lambda()#2}::operator()() const () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/EventProcessor.cc:445
#12 0x00007ffff728a2ff in void art::detail::ExceptionCollector::call<void art::EventProcessor::process<(art::Level)3>()::{lambda()#2}>(void art::EventProcessor::process<(art::Level)3>()::{lambda()#2}) () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/detail/ExceptionCollector.h:38
#13 0x00007ffff7283555 in void art::EventProcessor::process<(art::Level)3>() () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/EventProcessor.cc:444
#14 0x00007ffff72757f3 in void art::EventProcessor::process<(art::Level)2>()::{lambda()#2}::operator()() const () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/EventProcessor.cc:445
#15 0x00007ffff7283591 in void art::detail::ExceptionCollector::call<void art::EventProcessor::process<(art::Level)2>()::{lambda()#2}>(void art::EventProcessor::process<(art::Level)2>()::{lambda()#2}) () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/detail/ExceptionCollector.h:38
#16 0x00007ffff72758f3 in void art::EventProcessor::process<(art::Level)2>() () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/EventProcessor.cc:444
#17 0x00007ffff7267f3f in void art::EventProcessor::process<(art::Level)1>()::{lambda()#2}::operator()() const () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/EventProcessor.cc:445
#18 0x00007ffff727592f in void art::detail::ExceptionCollector::call<void art::EventProcessor::process<(art::Level)1>()::{lambda()#2}>(void art::EventProcessor::process<(art::Level)1>()::{lambda()#2}) () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/detail/ExceptionCollector.h:38
#19 0x00007ffff726803f in void art::EventProcessor::process<(art::Level)1>() () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/EventProcessor.cc:444
#20 0x00007ffff725b865 in void art::EventProcessor::process<(art::Level)0>()::{lambda()#2}::operator()() const () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/EventProcessor.cc:445
#21 0x00007ffff726807b in void art::detail::ExceptionCollector::call<void art::EventProcessor::process<(art::Level)0>()::{lambda()#2}>(void art::EventProcessor::process<(art::Level)0>()::{lambda()#2}) () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/detail/ExceptionCollector.h:38
#22 0x00007ffff725b965 in void art::EventProcessor::process<(art::Level)0>() () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/EventProcessor.cc:444
#23 0x00007ffff7249d27 in art::EventProcessor::runToCompletion()::{lambda()#1}::operator()() const () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/EventProcessor.cc:463
#24 0x00007ffff724ce0a in void art::detail::ExceptionCollector::call<art::EventProcessor::runToCompletion()::{lambda()#1}>(art::EventProcessor::runToCompletion()::{lambda()#1}) () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/detail/ExceptionCollector.h:38
#25 0x00007ffff7249daf in art::EventProcessor::runToCompletion() () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/EventProcessor/EventProcessor.cc:467
#26 0x00007ffff7d4af5a in art::run_art_common_(fhicl::ParameterSet const&, art::detail::DebugOutput) () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/Art/run_art.cc:247
#27 0x00007ffff7d49ba8 in art::run_art(int, char**, boost::program_options::options_description&, cet::filepath_maker&, std::vector<std::unique_ptr<art::OptionsHandler, std::default_delete<art::OptionsHandler> >, std::allocator<std::unique_ptr<art::OptionsHandler, std::default_delete<art::OptionsHandler> > > >&&, art::detail::DebugOutput&&) () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/src/art/Framework/Art/run_art.cc:129
#28 0x00007ffff7d4610f in artapp(int, char**) () at /scratch/workspace/art-rel-bld/SLF6/debug/build/art/v2_09_06/build-Linux64bit+2.6-2.12-e15-nu-debug/art/Framework/Art/artapp.cc:54
#29 0x0000000000401598 in main ()

All of the stuff in between the GDBTest class method call and main() is larsoft stuff that we probably don\'t care about (unless you found a bug in it, but it is probably a bug in your code instead). The `frame` command will tell you which function (stack frame) GDB is inside right now, and frame i will take you to the i\'th frame from the backtrace. You can print out the code around your current frame with list, and type list again to go forward in the code. list - goes backwards in the code. This way you don\'t have to exit GDB to inspect the code where an error is.

Since the program crashed, we can\'t inspect the value of variables in the code, so we\'re not sure what value of i caused the crash on line 59. We can tell GDB to stop at whenever a segfault happens and let us look around by running:

handle SIGSEGV nopass
handle SIGBUS nopass

and then we can run it again:

run -c gdbTest.fcl -S /dune/app/users/jhugon/tutorial/dunetpc_v06_69_00/fullpathnames_mcc10_protodune_beam_p2GeV_cosmics_3ms_sce_mcc10.0.txt

You can also print out the value of variables with p. It\'s pretty easy to print out local variables in the scope of your current stack frame.