# -x script.gdb
# -nx to skip .gdbinit
-def GetRendezVous():
- import sys
- if len( sys.argv ) != 3:
- raise RuntimeError("salome_process_attach have to take a rendez-vous file and gdb script")
- return sys.argv[1],sys.argv[2]
+from pathlib import Path
-import salome
-salome.salome_init()
-rdv,gdbfile = GetRendezVous()
-remoteNS = salome.naming_service.LoadIORInFile(rdv)
-remoteGlbs = salome.orb.string_to_object( remoteNS.Resolve("PID_TO_TRACK").decode() )
-import pickle
-pidToTrack = pickle.loads( remoteGlbs.getAttr("CTX0") )["pid"]
-returncode, stdout, stderr = remoteGlbs.execute(["gdb","-batch","-x",gdbfile,"attach",str(pidToTrack)])
-st = f"""returnCode = {returncode}
-stdout = {stdout.decode()}
-stderr = {stderr.decode()}
-"""
-print(st)
+def main():
+ DFT_PID_VALUE = -1
+
+ import argparse
+ from pathlib import Path
+ import salome
+ salome.salome_init()
+ parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter, description = "To be used in association of a process launched nested inside a salome_process_launcher session.")
+ parser.add_argument("rendez_vous_file", type=Path, help="Rendez vous file specified in corresponding salome_process_launcher.")
+ parser.add_argument("gdb_cmds_file", type=Path, help="GDB commands to be executed remotely.")
+ parser.add_argument("--pid", dest="pid_to_track", type=int, default=DFT_PID_VALUE, help="PID of process, the debugger will be attached on ( typically a son or a little son process of process whose PID is registred inside salome_process_launcher process)")
+ args = parser.parse_args()
+ rdv, gdbfile = args.rendez_vous_file, args.gdb_cmds_file
+ if not rdv.exists():
+ raise RuntimeError(f"Rendez-vous file {rdv} does not exist !")
+ gdbfile = gdbfile.absolute()
+ if not gdbfile.exists():
+ raise RuntimeError(f"GDB commands file {gdbfile} does not exist !")
+ gdbfile = gdbfile.absolute()
+ remoteNS = salome.naming_service.LoadIORInFile(f"{rdv}")
+ remoteGlbs = salome.orb.string_to_object( remoteNS.Resolve("PID_TO_TRACK").decode() )
+ import pickle
+ pidToTrack = pickle.loads( remoteGlbs.getAttr("CTX0") )["pid"]
+ if args.pid_to_track != DFT_PID_VALUE:
+ pidToTrack = args.pid_to_track
+ print(f"PID tracked : {pidToTrack}")
+ returncode, stdout, stderr = remoteGlbs.execute(["gdb","-batch","-x",f"{gdbfile}","attach",str(pidToTrack)])
+ st = f"""returnCode = {returncode}
+ stdout = {stdout.decode()}
+ stderr = {stderr.decode()}
+ """
+ print(st)
+
+if __name__ == "__main__":
+ main()
def handler(signum, frame):
os.kill( proc.pid, signal.SIGKILL )
-from pathlib import Path
-import argparse
-parser = argparse.ArgumentParser()
-parser.add_argument("-rdv","--rendz-vous",dest = "rdv", type=Path, help="Mandatory filename used as a rendez-vous file",required=True)
-parser.add_argument('rest', nargs=argparse.REMAINDER, help="Process to be launched. Attachable using salome_process_attach")
-args = parser.parse_args()
-if args.rest[0] != "--":
- raise RuntimeError("You have to preappend -- before commande to be launched")
-args.rest = args.rest[1:]
-salome.naming_service.DumpIORInFile( args.rdv )
+def main():
+ from pathlib import Path
+ import argparse
+ parser = argparse.ArgumentParser(description = "Process launcher hosting a servant that can execute system command in the same context than command launched.")
+ parser.add_argument("-rdv","--rendz-vous",dest = "rdv", type=Path, help="Mandatory filename used as a rendez-vous file",required=True)
+ parser.add_argument('rest', nargs=argparse.REMAINDER, help="Process to be launched. Attachable using salome_process_attach")
+ args = parser.parse_args()
+ if args.rest[0] != "--":
+ raise RuntimeError("You have to preappend -- before commande to be launched")
+ args.rest = args.rest[1:]
+ salome.naming_service.DumpIORInFile( args.rdv )
-signal.signal(signal.SIGINT, handler)
-signal.signal(signal.SIGTERM, handler)
-import subprocess as sp
-proc = sp.Popen(args.rest ,cwd = os.getcwd())
-from SALOME_GlobalsImpl import SALOME_GlobalsImpl
-glbs = SALOME_GlobalsImpl()
-import pickle
-glbs.setAttr("CTX0",pickle.dumps({"pid":proc.pid}))
-poa = salome.orb.resolve_initial_references("RootPOA")
-id_o = poa.activate_object(glbs)
-refPtr = poa.id_to_reference(id_o)
-salome.naming_service.Register(refPtr,"PID_TO_TRACK")
-proc.communicate()
-sys.exit( proc.returncode )
+ signal.signal(signal.SIGINT, handler)
+ signal.signal(signal.SIGTERM, handler)
+ import subprocess as sp
+ proc = sp.Popen(args.rest ,cwd = os.getcwd())
+ from SALOME_GlobalsImpl import SALOME_GlobalsImpl
+ glbs = SALOME_GlobalsImpl()
+ import pickle
+ glbs.setAttr("CTX0",pickle.dumps({"pid":proc.pid}))
+ poa = salome.orb.resolve_initial_references("RootPOA")
+ id_o = poa.activate_object(glbs)
+ refPtr = poa.id_to_reference(id_o)
+ salome.naming_service.Register(refPtr,"PID_TO_TRACK")
+ proc.communicate()
+ sys.exit( proc.returncode )
+
+if __name__ == "__main__":
+ main()
#include "SALOME_KernelServices.hxx"
#include <iostream>
+#include <mutex>
+#include <thread>
+
+static std::mutex global_mut;
void RegisterCompoInternal(const std::string& compoName, const std::string& compoIOR)
{
*a = 0;
}
+void goForLock()
+{
+ std::cout << "Start thread" << std::endl;
+ std::cout << "going to deadlock" << std::endl;
+ global_mut.lock();
+}
+
/*!
* This method wrapped into Python is useful to have a break point in C++ when complex python script is invoked in the stack
*/
void EntryForDebuggerBreakPoint()
{
- std::cout << "b KernelServices.cxx:53" << std::endl;
+ std::cout << "b KernelServices.cxx:64" << std::endl;
+}
+
+/*!
+ * This method leads to a deadlock to test robustness of higher level layers.
+ */
+void GenerateDeadLockForTestPurpose()
+{
+ global_mut.lock();
+ std::thread t1(goForLock);
+ t1.join();
}
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-#ifndef __KERNELSERVICES_HXX__
-#define __KERNELSERVICES_HXX__
+
+#pragma once
#include <string>
void RegisterCompoInternal(const std::string& compoName, const std::string& compoIOR);
std::string RetrieveCompoInternal(const std::string& compoName);
void GenerateViolentMemoryFaultForTestPurpose();
+void GenerateDeadLockForTestPurpose();
void EntryForDebuggerBreakPoint();
-
-#endif
void RegisterCompoInternal(const std::string& compoName, const std::string& compoIOR);
std::string RetrieveCompoInternal(const std::string& compoName);
void GenerateViolentMemoryFaultForTestPurpose();
+ void GenerateDeadLockForTestPurpose();
void EntryForDebuggerBreakPoint();
}