Solang compiler fails when sending lamports within a loop (targeting Solana) - llvm

I'm building a Solana program to manage payments to multiple accounts, however the compiler fails whenever a .send() call is made within a loop. For example, the following code compiles just fine:
function send( address[3] memory receivers ) external payable {
require(payable(receivers[0]).send(uint64(5)), "Transaction failed");
}
But the following code throws an error:
function send( address[3] memory receivers ) external payable {
for (uint i = 0; i < receivers.length; i++) {
require(payable(receivers[i]).send(uint64(5)), "Transaction failed");
}
}
LLVM ERROR: Unsupported dynamic stack allocation
I've also tried using .transfer() and .call(), all throw the same error. Is this behavior unsupported or is there a way I can resolve this issue?

This is an issue in solang v0.1.9. It should compile fine with solang latest main.
We should be release solang v0.1.10 shortly.

#sean-young, hi!
got the same error on Solang 0.1.13, when tried to call
address pda = create_program_address (["TokenAccountXXX", "seed"], _token );

Related

how to handle opencv error with a non-exception code base

I have a non-exception grpc service code base which uses “error code return” strategy to deals with all kinds of errors(when an error happens(not all, only the unhandleable ones), it causes a chain reaction all the way to the service response call and response the client request call with an error code)
now I have to rely on some third party library (say openCV), and I'm wondering how to handle the potential errors that may caused by openCV apis.
code examples:
#include<opencv2/opencv/hpp>
int A(args)
{
...
int errCode = B(); //this is how i handle all my internal api call or other thrid party same error-style api calls, it returns an int error code and checked
if(errCode)
{
//log...;
//resouce release...
return errCode;
}
...
return 0; //0 means succ call
}
int B(args)
{
...
cv::OPENCV_API(cv::Mat, cv::Mat,...args). // how to handle this api call?
...
}
and here is my questions:
1.what will happen if something is wrong with the opencv api call, I searched opencv error handling, see that most of it throws exceptions, so the whole service will be aborted?
if I don't want to use try {...} catch {...} in my code, how should I work with exception-throw style third party code to avlid them from crash my service?
3.say the worst, I have to use try {...} catch {...}, how should it be woked out? is some thing like below will work?(means that my service won't abort or cratch):
//int A() remains same
int B(args)
{
...
try
{
...
cv::OPENCV_API(cv::Mat, cv::Mat,...args). // how to handle this api call?
...
}
catch
{
log...;
int errCode = -1000;
return errCode;
}
return 0;
}
TL;DR if I don't use throw-exception syntax in my own code, how do I utilize and error-handling with thrid-party code that applys throw-exception syntax?

can we clear errono after function call

I have some function call like below, and want to print success after success call, but got failure, even the function actually behave correctly.
int myfunction() {
// does some linux sys call for example
int error = run_cmd ("ifconfig usb10 up");
int syserrorno = errno;
strerror(syserrorno);
return error;
}
int main(){
int error =1;
int retry = 0;
do {
error = myfunction();
retry++;
}
while ( error !=-1 && retry <3);
return 0;
}
Basically I tried to:
Run a syscal via myFunction, return error = 1 if fail or 0 if success.
The return error in myFunction is the same as in syscal.
The syscal is a posix spawn command that I reuse from library.
If there is error, print error, redo 3 times.
So I have 1st run of syscall unsuccessfully; it returns error and print out "unavailabe resources". It is expected.
The second time is successful as I check the usb10 and it is up. But it still prints out the same error instead of success.
Is there a way to print it correctly ?
When using errno, always set errno=0; before calling the function(s) whose status you want to check. C library and POSIX functions will set errno to a non-zero value if they encounter an error, but they do not reset it to zero if they succeed.
(The reason they work this way: When a function reporting via errno is actually implemented in terms of other functions, you don't want a later success to make errno forget about an earlier failure. This also makes it possible for user code to set errno=0;, call a number of closely-related library functions, and just check for overall success or failure after all of those calls.)

Check for nullptr Causes CTD

I have a block of code that I put in place to check for errors after a function runs. But this block of code is itself causing problems.
ErrorType *error;
CreateObject(..., &error); // Function argument is ErrorType**
if (error) // nullptr if no error
{
log << "Error details here." << std::endl;
log.close();
return false; // Causes application to PROPERLY quit
}
The debugger gives me a "memory access violation, line 3" error quite frequently and half the time, without using a debugger, this code causes a CTD while other times it executes just fine (When running the debugger, I can just hit "Continue" a few times until the block executes as intended.) Do I need to specify something like if (error != nullptr) to get it to work properly? Why is this error-checking block causing errors and how do I fix it?
Note that CreateObject() is an external API function that does not throw any exceptions.

Is it possible to catch a segfault with try/catch?

I did this test to see what happened:
try
{
int *x = 0;
*x = 1234;
}
catch(...)
{
cout << "OK";
}
But it throws a segfault, why does it not catch the segfault?
No you can`t.
A SEGFAULT isn't a regular exception.
The code you show is simply undefined behavior, and anything may be happen. There's no guarantee it ends up throwing an exception.
This answer is very specific to WINDOWS.
You can use Structured Exception Handling.
You have to call "SetUnhandledExceptionFilter"
https://msdn.microsoft.com/en-us/library/ms680634(v=vs.85).aspx
usage prototype:
You have to register a function at the beginning of application
SetUnhandledExceptionFilter(UnhandledExceptionFilterFunction);
Define your registered function, Handle your business.
Usually people collect coredumps and send Emails to dev team.
LONG WINAPI UnhandledExceptionFilterFunction(PEXCEPTION_POINTERS exception)
{
// The exception information is available in PEXCEPTION_POINTERS
}
Refer below link for PEXCEPTION_POINTERS
https://msdn.microsoft.com/en-us/library/windows/desktop/ms679331(v=vs.85).aspx
Here is the list of exception records that you get in "PEXCEPTION_POINTERS". The first one is "EXCEPTION_ACCESS_VIOLATION" (in LINUX terms SEGFAULT)
https://msdn.microsoft.com/en-us/library/windows/desktop/aa363082(v=vs.85).aspx

how commenting the following lines of code, can change the behviour of the previous ones?

NOTE: I do believe that this is not an openCV related problem but since the error occurred using this library it might be a point of interest.
In the following code, by giving the wrong parameter as cascade_name, the load function throws an exception which is expected.
The interesting point is that by commenting the two following lines after catch block, the code would not throw any exception at all.
my question is, how such a thing is possible at all?!
cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
cv::CascadeClassifier c;
try
{
c.load( std::string("") );
}catch(...)
{
cout << "Exception";
}
cv::FileStorage fs( std::string(cascade_name), cv::FileStorage::READ );
bool t2 = fs.isOpened();
bool t = c.empty();
if ( cascade == 0 )
return -1;
return 0;
It depends on the circumstances/assumptions about the program in general: it's possible, given the right set of circumstances.
For example:
You are running this function from multiple threads, and inside the openCV library the FileStorage object interacts (shares variables, etc.) with the CascadeClassifier object. The code path in one thread causes the other thread to error on the ::load method.
The times which I have seen things like this are (in order of likelihood):
- The compiler didn't rebuild with changes properly
- You didn't run the code you expected
- The addition of lines caused some problems with multi-threaded synchronization (either in your code, or inside the library)
- The addition code caused timings to change, which caused errors
Hope that helps.