Is it possible to set the exit status when terminating a Chapel program?
I can always use:
extern "exit" proc c_exit(status:c_int);
The following does the trick.
extern "exit" proc c_exit(status:c_int);
module M {
proc main() {
writeln("hello, world");
c_exit(1);
}
}
This sets the exit status to 1 - just wondering if there's a way that doesn't require a call into the C library.
You can just call exit(1). See proc exit in chapel docs .
Related
I want to get the exit status of a pipe in C++, both on Linux and on Windows, to check whether a command ran successfully.
On Linux (or POSIX more generally), it appears that the macros in <sys/wait.h> are needed to get the correct exit status, such as in the first answer to the question
Does pclose() return pipe's termination status shifted left by eight bits on all platforms?
#include <cstdio>
#include <iostream>
#ifdef _WIN32
#define popen _popen
#define pclose _pclose
#else
#include <sys/wait.h>
#endif
int main(){
FILE* pipe {nullptr};
pipe = popen( "echo 123", "r" );
int status {0};
status = pclose(pipe);
#ifndef _WIN32
/* ask how the process ended to clean up the exit code. */
if ( WIFEXITED(status) ){
/* Add code here if needed after pipe exited normally */
status = WEXITSTATUS(status);
} else if ( WIFSIGNALED(status) ){
/* Add code here if needed after pipe process was terminated */
status = WTERMSIG(status);
} else if ( WIFSTOPPED(status) ){
/* Add code here if needed after pipe stopped */
status = WSTOPSIG(status);
}
#else
/* but what about windows? */
#endif
std::cout << "Exit status: " << status << '\n';
return 0;
}
I couldn't find anything about Windows though. The C runtime lib reference for _pclose includes a remark about _cwait and states that
"The format of the return value [of _pclose] is the same as for _cwait, except the low-order and high-order bytes are swapped".
So how do I get the correct exit status on Windows?
I am using system api to invoke the powershell script and that script is not setting the errno to any value which is not giving me hint if the command execution is success or failure.
Below is my powersehll script which is simply setting the exit code, but this exit code is not set when I am calling this script using c++ system api.
test.ps1
#-------------------------------------------------------------------------------
function ExitWithCode {
#-------------------------------------------------------------------------------
param($exitcode)
$host.SetShouldExit($exitcode);
exit
}
ExitWithCode -exitcode 1
Execution of script using c++ program
string cmd = "";
std::getline(cin, cmd);
errno = 0;
cout <<" system " <<cmd << " ------> " << endl;
cout << system(cmd.c_str()) << " errno " << errno << endl;
Output of the c++ program
powershell -ExecutionPolicy Unrestricted -File "C:\test.ps1"
system powershell -ExecutionPolicy Unrestricted -File "C:\test.ps1" ------>
0 errno 0
system command output is 0 but the errno is alos set to 0. Any idea why the errno is not set?
The exit keyword in PowerShell sets the return code to 0 by default. As you are just calling exit without an argument, the return code will always be 0. Change your function to this:
#-------------------------------------------------------------------------------
function ExitWithCode {
#-------------------------------------------------------------------------------
param($exitcode)
exit $exitcode
}
ExitWithCode -exitcode 1
Or don't reinvent the wheel and just call:
exit 1
I need help running a program in an executable using GDB.
I have an executable file name vuln. I do not know the source code as I am doing a CTF. When I analyzed the executable, I found three exciting functions: main, vuln, and flag. Vuln func is vulnerable to BOF attack, but I do not want to go that way. What I am trying to do is run the executable in gdb, and I used print (void) flag(param1, param2) command to directly run flag func as this is supposed to give me a flag; however, it does not work as it says my parameters are incorrect which I am sure are not. I have also found out about the jump function, but I cannot pass any parameters.
So is there any way to run a function from executable with parameters properly or I would have to go through the pain of BOF.
GHIDRA disassembled code of FLAG and VULN Func are below.
void flag(int param_1, int param_2){
char local_50 [64];
FILE *local_10;
local_10 = fopen("flag.txt", "r");
if(local_10 != (FILE *)0x0){
fgets(local_50, 0x40, local_10);
if ((param_1 == -0x21524111) && (param_2 == -0x3f212ff3)){
printf(local_50);
}
return;
}
puts("Hurry up and try in on server side.");
exit(0);
}
void vuln(void)
{
char local_bc [180];
gets(local_bc);
puts(local_bc);
return;
}
print (void) flag(param1, param2)
Not sure what your values of param1 and param2 are, but this seems to work just fine for me:
echo "hello" > flag.txt
gdb -q ./a.out
(gdb) start
Temporary breakpoint 4 at 0x555555555307
Starting program: /tmp/a.out
Thread 1 "a.out" hit Temporary breakpoint 4, 0x0000555555555307 in main ()
(gdb) p (void)flag(-0x21524111, -0x3f212ff3)
hello
$2 = void
(gdb)
Error is displayed when compiling - "ld returned 1 exit status"
Error is displayed when compiling - "ld returned 1 exit status"
Error is displayed when compiling - "ld returned 1 exit status"
#include "WordProcessingMerger.h"
#include <exception>
#include <iostream>
#include <ctime>
using namespace DocxFactory;
using namespace std;
int main()
{
try
{
WordProcessingMerger& l_merger =
WordProcessingMerger::getInstance();
time_t l_start = clock();
l_merger.load(
"/opt/DocxFactory/exercises/templates/special_fields.dfw");
l_merger.setClipboardValue("Account", "Account", "12345678901");
l_merger.setClipboardValue("Account", "Active", "no");
l_merger.setClipboardValue("Account", "CustomerPic",
"/opt/DocxFactory/exercises/images/customer1.png");
l_merger.setClipboardValue("Account", "Comments",
"<h3>An unordered list:</h3>"
"<ul>"
"<li>List
item</li>"
"<li>List item</li>"
"<li>List item</li>"
"</ul>");
l_merger.paste("Account");
l_merger.save("/tmp/special_fields.docx");
cout<< "Completed (in "
<< (double) (clock() - l_start) / CLOCKS_PER_SEC
<< " seconds)."
<< endl;
}
catch (const exception& p_exception)
{
cout << p_exception.what() << endl;
}
}
ld returned 1 exit status
This is one of the common linker errors.. I am not sure your error is this one but I am sharing because I faced this once while using "G++".. It can occur if you have more then one ".cpp" file (for example: main.cpp, functions.cpp, etc.) and you are trying to compile only "main.cpp" and not others. The compiler will give error because it is unable to link to other files.
I was only trying to compile "main.cpp and not another ".cpp" file which had the functions defined on it so compiler was giving linker error (ld returned 1 exit status)..
The right command is to write all the ".cpp" files for compilation
Thanks
The error in your first picture says that ld.exe - that is, your linker - cannot find the file DocxFactory.lib.
You need to check that such a file actually exists in your D:\DocxFactory\lib directory. If it does not, then you need to either place a copy of DocxFactory.lib file in that directory or modify where ld is looking for DocxFactory.lib.
I'm wondering how I you can create and register a function from the C++-side that returns a table when called from the Lua-side.
I've tried a lot of things but nothing did really work. :/
(sorry for the long code)
This for example won't work, because Register() expects a "luaCFunction"-styled function:
LuaPlus::LuaObject Test( LuaPlus::LuaState* state ) {
int top = state->GetTop();
std::string var( state->ToString(1) );
LuaPlus::LuaObject tableObj(state);
tableObj.AssignNewTable(state);
if (var == "aaa")
tableObj.SetString("x", "ABC");
else if (var == "bbb")
tableObj.SetString("x", "DEF");
tableObj.SetString("y", "XYZ");
return tableObj;
}
int main()
{
LuaPlus::LuaState* L = LuaPlus::LuaState::Create(true);
//without true I can't access the standard libraries like "math.","string."...
//with true, GetLastError returns 2 though (ERROR_FILE_NOT_FOUND)
//no side effects noticed though
LuaPlus::LuaObject globals = L->GetGlobals();
globals.Register("Test",Test);
char pPath[MAX_PATH];
GetCurrentDirectory(MAX_PATH,pPath);
strcat_s(pPath,MAX_PATH,"\\test.lua");
if(L->DoFile(pPath)) {
if( L->GetTop() == 1 ) // An error occured
std::cout << "An error occured: " << L->CheckString(1) << std::endl;
}
}
When I try to set it up as a luaCFunction-function it just crashes (0x3) and says:
Assertion failed: 0, file C:\......\luafunction.h, line 41
int Test( LuaPlus::LuaState* state ) {
int top = state->GetTop();
std::string var( state->ToString(1) );
LuaPlus::LuaObject tableObj(state);
tableObj.AssignNewTable(state);
if (var == "aaa")
tableObj.SetString("x", "ABC");
else if (var == "bbb")
tableObj.SetString("x", "DEF");
tableObj.SetString("y", "XYZ");
tableObj.Push();
return state->GetTop() - top;
}
For clarification: from the Lua side I wanted it to be callable like:
myVar = Test("aaa")
Print(myVar) -- output: ABC
EDIT: The Print function comes from here. And was basically the cause for this to not work. Print can only print strings not tables... The C++ code from above works fine if you just return 1.
This is the documentation that came with my LuaPlus version btw: http://luaplus.funpic.de/
I really hope you can help me.. I'm already starting to think that it is not possible. :'(
edit:
I totally forgot to say that using PushStack() lead into an error because "the member does not exist"...
After some painstaking probing from the long comment discussion, I'm posting this answer to help summary the situation and hopefully to offer some useful advice.
The main issue the OP was running into was that the wrong print function was being called in the lua test script. Contrary to the original code shown the real code the OP was testing against was calling Print(myVar) which is a custom provided lua_CFunction and not the builtin print function.
Somehow along the way, this ended up creating some instantiation of template <typename RT> class LuaFunction and calling the overloaded operator()(). From inspecting the luafunction.h from luaPlus any lua errors that occurs inside this call will get swallowed up without any kind of logging (not a good design decision on luaPlus's part):
if (lua_pcall(L, 0, 1, 0)) {
const char* errorString = lua_tostring(L, -1); (void)errorString;
luaplus_assert(0);
}
To help catch future errors like this, I suggest adding a new luaplus_assertlog macro. Specifically, this macro will include the errorString so that the context isn't completely lost and hopefully help with debugging. This change hopefully won't break existing uses of luaplua_assert from other parts of the API. In the long run though, it's probably better to modify luaplus_assert so it actually includes something meaningful.
Anyway here's a diff of the changes made:
LuaPlusInternal.h
## -81,5 +81,6 ##
} // namespace LuaPlus
#if !LUAPLUS_EXCEPTIONS
+#include <stdio.h>
#include <assert.h>
#define luaplus_assert(e) if (!(e)) assert(0)
## -84,5 +85,6 ##
#include <assert.h>
#define luaplus_assert(e) if (!(e)) assert(0)
+#define luaplus_assertlog(e, msg) if (!(e)) { fprintf(stderr, msg); assert(0); }
//(void)0
#define luaplus_throw(e) assert(0)
//(void)0
LuaFunction.h
## -21,7 +21,7 ##
class LuaFunction
{
public:
- LuaFunction(LuaObject& _functionObj)
+ LuaFunction(const LuaObject& _functionObj)
: functionObj(_functionObj) {
}
## -36,7 +36,7 ##
if (lua_pcall(L, 0, 1, 0)) {
const char* errorString = lua_tostring(L, -1); (void)errorString;
- luaplus_assert(0);
+ luaplus_assertlog(0, errorString);
}
return LPCD::Type<RT>::Get(L, -1);
}
In the change above, I opted not to use std::cerr simply because C++ streams tend to be heavier than plain-old C-style io functions. This is especially true if you're using mingw as your toolchain -- the ld linker is unable to eliminate unused C++ stream symbols even if your program never uses it.
With that in place, here's an example where an unprotected call is made to a lua function so you can see the errorString printed out prior to the crash:
// snip...
int main(int argc, const char *argv[])
{
LuaStateAuto L ( LuaState::Create(true) );
LuaObject globals = L->GetGlobals();
globals.Register("Test", Test);
globals.Register("Print", Print);
if(argc > 1)
{
/*
if (L->DoFile(argv[argc - 1]))
std::cout << L->CheckString(1) << '\n';
/*/
L->LoadFile( argv[argc - 1] );
LuaFunction<int> f ( LuaObject (L, -1) );
f();
//*/
}
}
Running the above will trigger the crash but will include a semi-helpful error message:
g++ -Wall -pedantic -O0 -g -I ./Src -I ./Src/LuaPlus/lua51-luaplus/src plustest.cpp -o plustest.exe lua51-luaplus.dll
plustest.exe plustest.lua
plustest.lua:2: bad argument #1 to 'Print' (string expected, got table)Assertion failed!
Program: G:\OSS\luaplus51-all\plustest.exe
File: ./Src/LuaPlus/LuaFunction.h, Line 39
Expression: 0
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
first you may try to register the function using RegisterDirect(), this may avoid lua_CFunction's problem, check the luaplus manual.like this
LuaPlus::LuaObject globals = L->GetGlobals();
globals.RegisterDirect("Test",Test);
second if I remeber to create a table have two solutions,like this
//first
LuaObject globalsObj = state->GetGlobals();
LuaObject myArrayOfStuffTableObj = globalsObj.CreateTable("MyArrayOfStuff");
//second
LuaObject aStandaloneTableObj;
aStandaloneTableObj.AssignNewTable(state);
check whether you have use the right function.
third I remember the lua stack object is not the luaobject, they have a conversion, may be you can try this
LuaStackObject stack1Obj(state, 1);
LuaObject nonStack1Obj = stack1Obj;
forth, like the function Test() you have give above, the table tableObj you have pushing onto the lua stack, you must remember to clear the object.