Determing line number and file name of the perl file from within C++ - c++

I am working with Perl embedded in our application. We have installed quite a few C++ functions that are called from within Perl. One of them is a logging function. I would like to add the file name and line number of the Perl file that called this function to the log message.
I know on the Perl side I can use the "caller()" function to get this information, but this function is already used in hundreds of locations, so I would prefer to modify the C++ side, is this information passed to the C++ XSUB functions and if so how would I get at it?
Thanks.

This should work:
char *file;
I32 line;
file = OutCopFILE(PL_curcop);
line = CopLINE(PL_curcop);
Control ops (cops) are one of the two ops OP_NEXTSTATE and op_DBSTATE,
that (loosely speaking) are separate statements.
They hold information important for lexical state and error reporting.
At run time, PL_curcop is set to point to the most recently executed cop,
and thus can be used to determine our current state.
— cop.h

Can't you call perl builtins from XS? I confess I don't know.
If not, you could always do something like this:
sub logger { _real_logger(caller, #_) }
assuming logger is what your function is called (and you rename your C++ XS function to _real_logger. You could also do this, presumably, if you need to hide yourself in the call tree:
sub logger {
unshift #_, caller;
goto &_real_logger;
}
which is of course the normal form of goto used in AUTOLOAD.
These will add overhead, of course, but probably not a big deal for a logging function.

Related

Fastest way to make console output "verbose" or not

I am making a small system and I want to be able to toggle "verbose" text output in the whole system.
I have made a file called globals.h:
namespace REBr{
extern bool console_verbose = false;
}
If this is true I want all my classes to print a message to the console when they are constructing, destructing, copying or doing pretty much anything.
For example:
window(string title="",int width=1280,int height=720):
Width(width),Height(height),title(title)
{
if(console_verbose){
std::cout<<"Generating window #"<<this->instanceCounter;
std::cout<<"-";
}
this->window=SDL_CreateWindow(title.c_str(),0,0,width,height,SDL_WINDOW_OPENGL);
if(console_verbose)
std::cout<<"-";
if(this->window)
{
this->glcontext = SDL_GL_CreateContext(window);
if(console_verbose)
std::cout<<".";
if(this->glcontext==NULL)
{
std::cout<<"FATAL ERROR IN REBr::WINDOW::CONSTR_OPENGLCONTEXT: "<<SDL_GetError()<<std::endl;
}
}
else std::cout<<"FATAL ERROR IN REBr::WINDOW::CONSTR_WINDOW: "<<SDL_GetError()<<std::endl;
if(console_verbose)
std::cout<<">done!"<<endl;
}
Now as you can see I have a lot of ifs in that constructor. And I REALLY dont want that since that will slow down my application. I need this to be as fast as possible without removing the "loading bar" (this helps me determine at which function the program stopped functioning).
What is the best/fastest way to accomplish this?
Everying in my system is under the namespace REBr
Some variants to achieve that:
Use some logger library. It is the best option as it gives you maximum flexibility and some useful experience ;) And you haven't to devise something. For example, look at Google GLOG.
Define some macro, allowing you to turn on/off all these logs by changing only the macro. But it isn't so easy to write such marco correctly.
Mark your conditional flag as constexpr. That way you may switch the flag and, depending on its value, compiler will optimise ifs in compiled program. But ifs will still be in code, so it looks kinda bulky.
Anyway, all these options require program recompilation. W/o recompilation it is impossible to achieve the maximum speed.
I often use a Logger class that supports debug levels. A call might look like:
logger->Log(debugLevel, "%s %s %d %d", timestamp, msg, value1, value2);
The Logger class supports multiple debug levels so that I can fine tune the debug output. This can be set at any time through the command line or with a debugger. The Log statement uses a variable length argument list much like printf.
Google's logging module is widely used in the industry and supports logging levels that you can set from the command line. For example (taken from their documentation)
VLOG(1) << "I'm printed when you run the program with --v=1 or higher";
VLOG(2) << "I'm printed when you run the program with --v=2 or higher";
You can find the code here https://github.com/google/glog and the documentation in the doc/ folder.

In GDB is it possible to give an address relative (in lines) from the start of a function?

The subject line basically says it all.
If I give the location based on the file and a line number, that value can change if I edit the file. In fact it tends to change quite often and in an inconvenient way if I edit more than a single function during refactoring. However, it's less likely to change if it were (line-)relative to the beginning of a function.
In case it's not possible to give the line offset from the start of a function, then is it perhaps possible to use convenience variables to emulate it? I.e. if I would declare convenience variables that map to the start of a particular function (a list that I would keep updated)?
According to help break neither seems to be available, but I thought I'd better ask to be sure.
(gdb) help break
Set breakpoint at specified line or function.
break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM] [if CONDITION]
PROBE_MODIFIER shall be present if the command is to be placed in a
probe point. Accepted values are `-probe' (for a generic, automatically
guessed probe type) or `-probe-stap' (for a SystemTap probe).
LOCATION may be a line number, function name, or "*" and an address.
If a line number is specified, break at start of code for that line.
If a function is specified, break at start of code for that function.
If an address is specified, break at that exact address.
With no LOCATION, uses current execution address of the selected
stack frame. This is useful for breaking on return to a stack frame.
THREADNUM is the number from "info threads".
CONDITION is a boolean expression.
Multiple breakpoints at one place are permitted, and useful if their
conditions are different.
Do "help breakpoints" for info on other commands dealing with breakpoints.
It's a longstanding request to add this to gdb. However, it doesn't exist right now. It's maybe sort of possible with Python, but perhaps not completely, as Python doesn't currently have access to all the breakpoint re-set events (so the breakpoint might work once but not on re-run or library load or some other inferior change).
However, the quoted text shows a nicer way -- use an probe point. These are so-called "SystemTap probe points", but in reality they're more like a generic ELF + GCC feature -- they originated from the SystemTap project but don't depend on it. These let you mark a spot in the source and easily put a breakpoint on it, regardless of other edits to the source. They are already used on linux distros to mark special spots in the unwinder and longjump runtime routines to make debugging work nicely in the presence of these.
I understand that this is an old question, but I still could not find a better solution even now in 2017. Here's a Python solution. Maybe it's not the most robust/cleanest one, but it works very well in many practical scenarios:
class RelativeFunctionBreakpoint (gdb.Breakpoint):
def __init__(self, functionName, lineOffset):
super().__init__(RelativeFunctionBreakpoint.calculate(functionName, lineOffset))
def calculate(functionName, lineOffset):
"""
Calculates an absolute breakpoint location (file:linenumber)
based on functionName and lineOffset
"""
# get info about the file and line number where the function is defined
info = gdb.execute("info line "+functionName, to_string=True)
# extract file name and line number
m = re.match(r'Line[^\d]+(\d+)[^"]+"([^"]+)', info)
if not m:
raise Exception('Failed to find function %s.' % functionName)
line = int(m.group(1))+lineOffset #add the lineOffset
fileName = m.group(2)
return "%s:%d" % (fileName, line)
USAGE:
basic:
RelativeFunctionBreakpoint("yourFunctionName", lineOffset=5)
custom breakpoint:
class YourCustomBreakpoint (RelativeFunctionBreakpoint):
def __init__(self, funcName, lineOffset, customData):
super().__init__(funcName, lineOffset)
self.customData = customData
def stop(self):
# do something
# here you can access self.customData
return False #or True if you want the execution to stop
Advantages of the solution
relatively fast, because the breakpoint is set only once, before the execution starts
robust to changes in the source file if they don't affect the function
Disadvatages
Of course, it's not robust to the edits in the function itself
Not robust to the changes in the output syntax of the info line funcName gdb command (probably there is a better way to extract the file name and line number)
other? you point out

c++ software passing arguments method

I have a problem related to passing arguments to a C++ compiled executable. The program emulate the behaviour of a particular inference engine: the setup of the engine is load at runtime from an XML file, and then I want to call it from command line with different input values.
The characteristic of the input are:
Every time that I call the program, the input structure is different, because the system itself is different.
The input is a set of couple {name, value}, one for each part of the system.
I have to separate the configuration XML from the input.
I call the program from a PHP or Node.js server, since it return a result that I expose to the outside through an API.
Input value are obtained from an HTTP post request.
By now I have tried these solutions:
Pass it from the command line ex: "./mysoftware input1 value1 input2 value2 ...etc". A little unconfortable, since I have up to 200 input.
Create a file with all the couples name,value and then call the program that parse the file and then destroy at the end. This is a bottleneck of performance for my API, because at every call I have to create and destruct a file.
Does anyone know a better way to approach this problem?
3. Pass the values to the program via the standard input stream and read them from std::cin inside your C++ program.

QSettings - Sync issue between two process

I am using Qsettings for non gui products to store its settings into xml files. This is written as a library which gets used in C, C++ programs. There will be 1 xml file file for each product. Each product might have more than one sub products and they are written into xml by subproduct grouping as follows -
File: "product1.xml"
<product1>
<subproduct1>
<settings1>..</settings1>
....
<settingsn>..</settingsn>
</subproduct1>
...
<subproductn>
<settings1>..</settings1>
....
<settingsn>..</settingsn>
</subproductn>
</product1>
File: productn.xml
<productn>
<subproduct1>
<settings1>..</settings1>
....
<settingsn>..</settingsn>
</subproduct1>
...
<subproductn>
<settings1>..</settings1>
....
<settingsn>..</settingsn>
</subproductn>
</productn>
The code in one process does the following -
settings = new QSettings("product1.xml", XmlFormat);
settings.setValue("settings1",<value>)
sleep(20);
settings.setValue("settings2", <value2>)
settings.sync();
When the first process goes to sleep, I start another process which does the following -
settings = new QSettings("product1.xml", XmlFormat);
settings.remove("settings1")
settings.setValue("settings3", <value3>)
settings.sync();
I would expect the settings1 to go away from product1.xml file but it still persist in the file - product1.xml at the end of above two process. I am not using QCoreApplication(..) in my settings library. Please point issues if there is anything wrong in the above design.
This is kind of an odd thing that you're doing, but one thing to note is that the sync() call is what actually writes the file to disk. In this case if you want your second process to actually see the changes you've made, then you'll need to call sync() before your second process accesses the file in order to guarantee that it will actually see your modifications. Thus I would try putting a settings.sync() call right before your sleep(20)
Maybe you have to do delete settings; after the sync() to make sure it is not open, then do the writing in the other process?
Does this compile? What implementation of XmlFormat are you using and which OS? There must be some special code in your project for storing / reading to and from Xml - there must be something in this code which works differently from what you expect.

Calling Lua function without executing script

I am embedding Lua into a C/C++ application. Is there any way to call a Lua function from C/C++ without executing the entire script first?
I've tried doing this:
//call lua script from C/C++ program
luaL_loadfile(L,"hello.lua");
//call lua function from C/C++ program
lua_getglobal(L,"bar");
lua_call(L,0,0);
But it gives me this:
PANIC: unprotected error in call to Lua API (attempt to call a nil value)
I can only call bar() when I do this:
//call lua script from C/C++ program
luaL_dofile(L,"hello.lua"); //this executes the script once, which I don't like
//call lua function from C/C++ program
lua_getglobal(L,"bar");
lua_call(L,0,0);
But it gives me this:
hello
stackoverflow!!
I am wanting this:
stackoverflow!
This is my lua script:
print("hello");
function bar()
print("stackoverflow!");
end
As was just discussed in #lua on freenode luaL_loadfile simply compiles the file into a callable chunk, at that point none of the code inside the file has run (which includes the function definitions), as such in order to get the definition of bar to execute the chunk must be called (which is what luaL_dofile does).
Found out that the script must be run to call the function.
One possible solution / hack (and please bear in mind that I'm currently unable to test this)...
Insert a dummy "return;" line at the top of your LUA code.
Load your file into a string (like you would in preparation for using luaL_loadstring())
Now it should be a simple matter of using printf_s("return;\r\n%s", [pointer to string holding actual LUA code])
Now you can luaL_loadstring() the concatenated string
The code will still execute, but it should get cut off before it can actually reach anything that does something (in your print("hello"); example, the print line would become unreachable). It should still have updated the list of all the function prototypes and you should now be able to use lua_get() to reference the functions.
NOTE: For those who don't know "\r\n" are the escape codes representing a newline on the Windows OS, and it MUST be those slashes...   IE: THIS \r\n       NOT THIS /r/n