GCC plugin: 'internal compiler error' in passes.c - gcc

I have been writing a GCC inter procedural plugin where I have to insert GIMPLE statements
at certain points in the program. After this I perform a data flow analysis on the complete
program. When I am done with my analysis I am removing those newly inserted GIMPLE statements.
My analysis is getting completed but just before exiting from it the following message is generated:
internal compiler error: in execute_ipa_pass_list, at passes.c:1817
This is surely because of the insertion of GIMPLE statements, if I don't do that I won't get this error message.
Could anyone help me out and explain what is the problem and how to fix it?

This usually happens when GCC code contains an assertion which turns out to be false.
The line 1817 in passes.c (which is part of the GCC sources, in the gcc sub-directory of the GCC source tree) has a piece of code which looks like:
gcc_assert (some_condition);
In your case, some_condition was false, but the compiler expects it to be always true (this is why the author of the code wrote the assertion in the first place).
You did something in your plugin which made it false, and you need to fix it.
What did you do wrong? It really depends. Open up passes.c and find that line, and see what it is checking. In my copy of GCC, the relevant function reads:
void
execute_ipa_pass_list (struct opt_pass *pass)
{
do
{
/* An assertion. */
gcc_assert (!current_function_decl);
/* Another assertion. */
gcc_assert (!cfun);
/* Another assertion. */
gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
if (execute_one_pass (pass) && pass->sub)
{
if (pass->sub->type == GIMPLE_PASS)
{
invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_START, NULL);
do_per_function_toporder ((void (*)(void *))execute_pass_list,
pass->sub);
invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_END, NULL);
}
else if (pass->sub->type == SIMPLE_IPA_PASS
|| pass->sub->type == IPA_PASS)
execute_ipa_pass_list (pass->sub);
else
gcc_unreachable ();
}
/* Another assertion. */
gcc_assert (!current_function_decl);
cgraph_process_new_functions ();
pass = pass->next;
}
while (pass);
}
There are four gcc_assert statements. Your plugin caused one of them to become false. i.e. you messed with one of the variables:
current_function_decl
cfun
pass->type
This is probably what's wrong.

Related

Unable to Call Function in Go debugger

I am following the "Little Go Book" by Karl Seguin, in order to learn Go.
My working environment is Visual Studio Code.
Upon debugging, when I try to call a function from the debug console, i get the following error:
"function calls not allowed without using 'call'", if I try using "call fib(10)", i get "Unable to eval expression: "1:6: expected 'EOF', found fib".
This is the function I am trying to evaluate:
//Fibonnaci
func fib(n int) int64 {
if n == 0 {
return 0
} else if n == 1 {
return 1
} else {
return fib(n-1) + fib(n-2)
}
}
If i try to call the function from the code itself ( from the main() for instance, it works perfectly).
However, if I set a breakpoint and try to call the same function from the debugger console, I get the below error:
Eval error: function calls not allowed without using 'call'
call fib(10)
Unable to eval expression: "1:6: expected 'EOF', found fib"
Failed to eval expression: {
"Expr": "call fib(10)",
"Scope": {
"goroutineID": 1,
"frame": 0
},
"Cfg": {
"followPointers": true,
"maxVariableRecurse": 1,
"maxStringLen": 64,
"maxArrayValues": 64,
"maxStructFields": -1
}
}
Looks like "Function calls via delve 'call' are not supported" yet github issue in microsoft/vscode-go repo :(
The issue vscode-go issue 100 "debug: support function calls via delve 'call'" just got closed with PR 101 and commit 5a7752c / CL 249377
Delve supports function calls. Even though it is still experimental and can be applied only to a limited set of functions, this is a useful feature, many vscode-go users long for.
Unlike other javascript/typescript debuggers, delve treats function calls specially and requires different call paths than usual expression evaluation.
That is because Go is a compiled, runtime-managed GC language, calling a function safely from debugger is complex.
DAP and VS Code UI does not distinguish function calls and other expression evaluation either, so we have to implement this in the same evaluateRequest context.
We use a heuristic to guess which route (call or expression evaluation) we need to take based on evaluateRequest's request.
This is part of the 0.17.0 milestone, yet to be released, and available for now in the nightly build.

What's os.geteuid() do?

I was trying to debug a Python 2 script running on Raspbian (Raspberry Pi flavoured Debian Linux) which had code like
euid = os.geteuid()
if euid != 0:
print("you must be root!")
exit(1)
It seemed like, in the user's environment, euid would sometimes be nonzero even if the script was called with sudo.
To investigate whether this was actually the case, I tried to figure out what os.geteuid() is actually doing.
Since the os module is pretty OS-specific by its nature, the source doesn't actually have a clear definition for os.geteuid().
I also tried hg cloneing the source and compiling it, then using inspect.findsource(os.geteuid), but:
TypeError: <built-in function geteuid> is not a module, class, method, function, traceback, frame, or code object
It's... a builtin? Then "geteuid" in dir(__import__("__builtin__")) should be True, but it isn't.
Is geteuid's definition hidden because it could be spoofed into returning the wrong thing (and that would be bad)? Where can I see these sorts of functions' actual source?
ASCII stupid question, get a stupid ANSI.
I did try full-text searching the source, but apparently I used the wrong command the first time and gave up.
$ grep -rnw '.' -e "geteuid"
./Misc/setuid-prog.c:129: uid_t euid = geteuid();
./Lib/site.py:209: if hasattr(os, "getuid") and hasattr(os, "geteuid"):
./Lib/site.py:211: if os.geteuid() != os.getuid():
./Lib/test/test_shutil.py:84: #unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
./Lib/test/test_httpservers.py:339: if os.name == 'posix' and os.geteuid() != 0:
./Lib/test/test_httpservers.py:395:#unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
./Lib/test/test_spwd.py:8:#unittest.skipUnless(hasattr(os, 'geteuid') and os.geteuid() == 0,
./Lib/test/test_posix.py:44: "getegid", "geteuid", "getgid", "getgroups",
./Lib/test/test_argparse.py:1532:#unittest.skipIf(hasattr(os, 'geteuid') and os.geteuid() == 0,
Binary file ./Lib/tarfile.py matches
./Lib/rexec.py:148: 'getcwd', 'getuid', 'getgid', 'geteuid', 'getegid')
Binary file ./Modules/posixmodule.o matches
./Modules/posixmodule.c:4047:"geteuid() -> euid\n\n\
./Modules/posixmodule.c:4053: return _PyInt_FromUid(geteuid());
./Modules/posixmodule.c:8944: {"geteuid", posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
./Doc/library/rexec.rst:234: 'times', 'uname', 'getpid', 'getppid', 'getcwd', 'getuid', 'getgid', 'geteuid',
./Doc/library/os.rst:136:.. function:: geteuid()
Binary file ./python matches
Binary file ./libpython2.7.a matches
./Modules/posixmodule.c:4053, indeed:
#ifdef HAVE_GETEUID
PyDoc_STRVAR(posix_geteuid__doc__,
"geteuid() -> euid\n\n\
Return the current process's effective user id.");
static PyObject *
posix_geteuid(PyObject *self, PyObject *noargs)
{
return _PyInt_FromUid(geteuid());
}
#endif
I don't know what I expected, subprocess.check_output(["id"])?
It uses the C standard library, it's never wrong.

Clang does not compile a g++ project

When trying to compile a g++ project with the clang compiler, there is a strange error showing up.
Here is the snippet of the source file:
std::set<TTransportNetworkId> l_transportNetworkIds;
SelectionResultContainer l_searchResult = p_repo.rootMoc() / LnAny("LNBTS") / LnAny("LNMME");
BOOST_FOREACH(const SelectionResult & l_lnmmeSR, l_searchResult)
{
const MoLnmme & l_lnmme = l_lnmmeSR;
l_transportNetworkIds.insert(*l_lnmme.transportNwId);
}
The error message is:
conditional expression is ambiguous; 'rvalue_probe<Rrom::DataRep::SelectionResultContainer>' can be converted to 'Rrom::DataRep::SelectionResultContainer' and vice versa
BOOST_FOREACH(const SelectionResult & l_lnmmeSR, l_searchResult)
Conditions are:
The file compiles fine with gcc_4.3.2
clang in version 3.2 throws the above error
Already tried to include the latest boost library which results in the same error
My guess is that clang handles rvalue conditions differently than this gcc version does.
clang is supposed to be a drop-in-replacement for gcc, so how can one get rid of this error without touching the source file?
Are there any options in clang which somehow disables these kind of errors?!
UPDATE:
I could create an example source file, which you can reproduce for yourself:
#include <vector>
#include <boost/foreach.hpp>
class A : public std::vector<int>
{
public:
template <class T>
operator const T &() const;
};
void foo(){
A colA;
int b = 1;
BOOST_FOREACH(b, colA)
{
;
}
}
When compiled with clang 3.2 the above error is raised, with some additional insights to where exactly the error occurs:
error: conditional expression is ambiguous; 'rvalue_probe<A>' can be converted to 'A' and vice versa BOOST_FOREACH(b, colA)
expanded from macro 'BOOST_FOREACH' f (boost::foreach_detail_::auto_any_t BOOST_FOREACH_ID(_foreach_col) = BOOST_FOREACH_CONTAIN(COL))
expanded from macro 'BOOST_FOREACH_CONTAIN' BOOST_FOREACH_EVALUATE(COL)
expanded from macro 'BOOST_FOREACH_EVALUATE' (true ? boost::foreach_detail_::make_probe((COL), BOOST_FOREACH_ID(_foreach_is_rvalue)) : (COL))
This code is compiled without errors with gcc_4.7.2.
Any ideas why the two compilers behave differently?
I found the solution in this document, see http://www.boost.org/doc/libs/1_43_0/boost/foreach.hpp
Snippet:
// Some compilers do not correctly implement the lvalue/rvalue conversion
// rules of the ternary conditional operator.
# if defined(BOOST_FOREACH_NO_RVALUE_DETECTION)
So, when providing a -DBOOST_FOREACH_NO_RVALUE_DETECTION definition option to clang, the error disappears.
Still the question remains whether gcc or clang is right or wrong on this point.

Xcode 4.6 if statement with &&

My problem is
-(IBAction)setAction:(id)sender{
if ([labelOne.text isEqual: #"One"] && [labelTwo.text isEqual: #"Two"]) {
labelShow.text = #"Yes it works :)";
}
}
And if i build it. It show me the error code: Thread 1: signal SIGBART
but it works if i do it like this
-(IBAction)setAction:(id)sender{
if ([labelOne.text isEqual: #"One"]) {
labelShow.text = #"Yes it works :)";
}
}
What can I do, that the First one works?:)
The SIBABRT implies that either labelTwo or labelTwo.text is pointing to bad memory.
First figure out which pointer is bad, and then debug to see why. Also, provide a crash log when possible. There should be an error message associated in your debug output pane.
Check out this debugging tutorial.

CUDAPP 1.1 cudppSort configuration error (Invalid configuration argument)

I am trying to call cudppSort to sort a set of keys/values. I'm using the following code to set up the sort algorithm:
CUDPPConfiguration config;
config.op = CUDPP_ADD;
config.datatype = CUDPP_UINT;
config.algorithm = CUDPP_SORT_RADIX;
config.options = CUDPP_OPTION_KEY_VALUE_PAIRS | CUDPP_OPTION_FORWARD | CUDPP_OPTION_EXCLUSIVE;
CUDPPHandle planHandle;
CUDPPResult result = cudppPlan(&planHandle, config, number_points, 1, 0);
if (CUDPP_SUCCESS != result) {
printf("ERROR creating CUDPPPlan\n");
exit(-1);
}
The program exits, however on the line:
CUDPPResult result = cudppPlan(&planHandle, config, number_points, 1, 0);
and prints to stdout:
Cuda error: allocScanStorage in file 'c:/the/path/to/release1.1/cudpp/src/app/scan_app.cu' in line 279 : invalid configuration argument.
I looked at the line in scan_app.cu. It is,
CUT_CHECK_ERROR("allocScanStorage");
So apparently my configuration has an error that is causing the allocScanStorage to bomb out. There are only two calls to CUDA_SAFE_CALL in the function and I don't see a reason why either has anything to do with the configuration.
What is wrong with my configuration?
So that this doesn't sit around as an unanswered question (I'm not sure if this is the right SO etiquette but it seems like an answered question shouldn't sit around unanswered...), I'm copying the comment I made above here as an answer since it was the solution:
I figured this out (I'm still learning CUDA at the moment.) Because the error checking is asynchronous errors can show up in strange places if you don't check for them from time to time. My code had caused an error before I called cudppPlan but because I didn't check for errors the cudppPlan reported the error as if it was in cudppPlan.

Resources