I need to create a system call in Minix for a homework assignment. I've gotten most of the set up finished, but for some reason the function that the system call is actually calling isn't being found correctly. (Pardon any bad wording choices, I'm not sure the best words to explain this).
I've created a mylib.h in /usr/include (and /usr/src/include), with the following code:
#include <lib.h>
#include <unistd.h>
#include <stdio.h>
int mycall(){
message m;
return (_syscall(PM_PROC_NR, MYCALL, &m));
}
I also added mylib.h to the appropriate Makefile.
I've defined MYCALL in /usr/src/include/minix/callnr.h, and I've added do_mycall to the corresponding slot in /usr/src/servers/pm/table.h.
I've added int do_mycall(void); to /usr/src/servers/pm/proto.h, and I added a simple function declaration in misc.c.
int do_mycall(void){
printf("I've been called");
return 0;
}
I've also tried placing it in it's own .c file, which I added to the Makefile in that directory.
I performed make in /usr/src/servers/pm/ and /usr/src/include, and make includes in /usr/src/releasetools.
However, when I call mycall(), and catch the return value, it's -1.
I've added some prints, and I can tell that the function in mylib.h is being called, and MYCALL is correctly defined as the index in table.h, and table.h should have the do_mycall line correctly in place (though I don't really know how to test that it's there upon execution). So, all I can tell is that in _syscall, do_mycall isn't correctly mapping to it's function.
I tried replacing the prototype in photo.h with just the code in misc.c (so the prototype would be missing), but nothing happened differently, and make didn't complain.
Can anyone help me figure out what's causing this, or how I can narrow down where the disconnect is here?
If anyone knows where _syscall is defined, that might help, since I could maybe add some prints in it to figure out how far it's getting.
I was unable to find a specific cause, but after exhausting all options I could find, the issue appears to have been with my virtual machine. I repeated everything I did to set up the system call on VMware Player, instead of VirtualBox, and everything worked fine.
Related
Though the title reads dll, the actual library loaded is an exe. Suppose I have an exe file testlib.exe. I need to call a function from it, let it be func(). What I am doing is:
#include <windows.h>
#include <stdio.h>
typedef char* (__stdcall *f_func)();
int main()
{
HINSTANCE hGetProcIDDLL = LoadLibrary("testlib.exe");
f_func func = (f_func)GetProcAddress(hGetProcIDDLL, "func");
printf(func());
return 0;
}
Now most of the times I run the program it gives the correct output, but in some cases (1 out of 8 for example) it gives either garbage text or values of some other variables in testlib.exe. I identify it's due to wrong memory reference but can neither explain nor solve it.
My os is windows and I'm using mingw gcc. I do not use MSVS as it does not fit well in code portability.
PS: The testlib.exe is well built and I cannot change it. It is unlikely to have any problem. I tried different versions and also it's running in other build systems well. Also it is a release build, so less hope in debugging.
UPDATE:
I've seen this question, it says that it is possible by patching the IAT table. My point is completly different. I am using a function that is neither initialised by main nor by dllmain.
Actually what I found that GetProcAddress gives right function pointer everytime. What gets messed is the return object. For example if the function in exe library is:
const char* func() {
return "Sometext";
}
then sometimes the reference to "sometext is sometimes wrong. I do suspect randomised loading but I'm not sure. I renamed the exe as dll but no change observed.
I am using visual studio 2017 .
First I wrote the following code :
void main()
{
printf("abcdefgh %d hjhjh %d", 5, 6);
getch();
}
It ran perfectly fine .
But after that I modified the code to the following :
void main()
{
char abc[100];
strcpy_S(abc, "premraj");
printf("%s", abc);
printf("abcdefgh %d hjhjh %d", 5, 6);
getch();
}
But now I am getting an error with getch stating that "'getch' undefined, assuming extern returning int"
But this new code has been built on the existing code which recognized getch perfectly , how can it not recognize getch the second time ?
I checked out the following question :
getch() is working without conio.h - how is that possible?
which also carried a similar problem but here with modifications only I got this error .
There is an informative answer there by user named "Fatal Error" but still I would like to know about this intriguing phenomenon that is coming in after modifications . What can be the reason behind this ?
P.S : The following was my header file declarations for the first time :
#include <stdio.h>
and the following for the second time :
#include <stdio.h>
#include <string.h>
Once upon a time, if you called a function which the compiler had never heard of, like this:
#include <stdio.h>
int main()
{
int x = foo();
printf("%d\n", foo);
}
Anyway, if you did that, the compiler quietly assumed that foo() was a function returning int. That is, the compiler behaved just as if you had typed
extern int foo();
somewhere before you called foo.
But in, I think, C99, the language was changed. It was no longer legal to call a function you had not explicitly declared. Because there was lots and lots of code out there that was written under the previous set of rules, most compilers did not immediately begin rejecting the old-style code. Some continued to quietly assume that unrecognized functions returned int. Others -- like yours -- began noisily assuming that unrecognized functions returned int, emitting warnings along the lines of "'foo' undefined, assuming extern returning int".
It sounds like your question is that some time ago, your code containing calls to getch() was accepted without warning, but today, you're getting the warning "'getch' undefined, assuming extern returning int". What changed?
One possibility is that your code changed slightly. If your code used to contain the line
#include <conio.h>
somewhere, that file would have contained a declaration along the lines of
extern int getch();
and this would have goven the compiler the declaration that it needed, and you would not have gotten the warning. But if today your code does not contain that #include line, that explain why the warning started cropping up.
It's also possible that your compiler has changed somehow. It's possible you're using a new version of the compiler, that's more fussy, that has gone from quietly assuming, to normally assuming. Or, it's possible that your compiler options have changed. Many compilers can be configured to accept different variants of the language, corresponding to the different versions of the language standards that have been released over the years. For example, if some time ago your compiler was compiling for language standard "C89", but today, it's doing "C99" or "C11", that would explain why it's now being noisy with this warning.
The change in the compiler could be a change in the defaults as configured by a system administrator, or a change in the way you're invoking the compiler, or a change in your project's Makefile, or a change in the language settings in your IDE, or something like that.
A few more points:
getch is not a Standard C function; it's specific to Windows. Your program would be more portable, in general, if you didn't use it. Are you sure you need it? (I know what it's for; what I don't know if there's some other way of keeping your program's output window on the screen after if exits.)
You should get in the habit of declaring main() as int, not void. (void will work well enough, but it's not correct, and if nothing else, you'll get lots of negative comments about it.)
I think there's something wrong with your call to strcpy_S, too,
I have a very frustrating bug that others on the team can't reproduce. I have tried cleaning the project, wiping the directory, pulling from the repository, rebuilding, and even testing in VS 2013.
Background: a.c, b.c, c.c and b.inc are all compiled into a DLL (assume they are externed). setfoo() is called first from managed code. So far so good.
Later on, testfoo() is called. The global variable is fine, there are no issues. Then testfoo2() is called. This is where things get interesting. I have the memory debugger on with foo's address, and it will read 4 in memory. However, if you hover over code in visual studio, it returns 0!. Also, it will output 0. There are many global variables (including FILE handles and they are reset to zero(causing nasty ASSERT failures), ONLY in c.c, but are fine when inspected with the debugger). There are many other x.c modules with that include that have no issues.
Ok, now testfoo() is called again. Everything is fine in b.c world. The scary part is that the issue happens on only on my workstation! Any clues on how to debug this?
This is from my memory, I believe the code is very close to this skeleton:
b.inc
int foo;
a.c
#include <b.inc>
void setfoo(){
foo = 4;
}
b.c
#include <b.inc>
void testfoo(){
printf(foo); //works
}
c.c
#include <b.inc>
void testfoo2(){
printf(foo); //foo is now 0
}
To Add: This is very complex, legacy code (think 70s), in a very large company and not much can be changed. There are thousands of variables that would be affected if we start adding extern. Also, I tried extern on one variable, and it still has an issue with that file.
I left out one tidbit. 'testfoo2()' launches in a managed thread. Again, this seems to be related to my machine, could be some setting in visual studio, dunno at this point, we want to just re-image the box.
You need to declare as extern:
extern int foo;
And then in one (and only one) of the source files you define it:
int foo;
That way there is only one symbol in one source file, and all other sources including the header know to link to it. If you omit extern then each source file thinks it has its own local, private copy of foo.
So which file should define it? The one that is most relevant. I would say a.c, since that provides functions to operate on foo. I would consider that file to be the 'owner'. However, it's a little confusing because you declare it in b.inc, suggesting that b.c is the owner.
try this.
b.inc
extern int foo;
a.c
#include <b.inc>
int foo;
void setfoo(){
foo = 4;
}
I posted this in another thread, but I'll duplicate the answer here. It is a pretty subtle bug that may save you a few hours:
Ok, here is what happened: (In case you run into this in the future)
1)On a prior build someone split all the C# Extern dll calls into two files.( I wasn't told)
2)They created a post build process to copy the dll (see where this is going) to another directory.
3)There was a user settings file involved which wasn't in the repo, but had a default in code.
4)One of the extern DLL functions kept my original default (in filea.cs), but the new default (fileb.cs) pointed to the post build location.
There is no real way to reflect the dll's path at runtime, as far as I know....
So, when I entered the function with the dll copy, OF COURSE there are no global variables, because it is a FRESH COPY of the dll. That is expected behavior.
The memory debugger was correct, because somewhere the other dll was in memory holding the correct variable.
How could I prevent this in the future? It seemed VS was duped when it loaded a copy of the same dll.
I'm having some trouble with C standard functions. As an example, I'm getting that error in the memcpy function, even passing the right arguments to it.
I've included a header as #include "header.h", and I've included , and so in the "header.h" file.
(I'm also getting this error with strcpy, strtok, and some other standard functions, all respective headers included in "header.h")
Can anyone please help me with this? I'm running out of time to deploy this work...
Thanks in advance
It seems it was some trouble within eclipse. I right clicked one of those functions, selected Source->Add includes and it solved the problem (but didn't added any header).
I hope this can be helpful for someone else
Since you have not posted your code I assume that you have not included the following lines of code, at the top of your file:
#include <string.h>
In case your are using a C++ compiler (i.e. g++) then:
#include <cstring>
I went through all sorts of quine problems, but my task was to get a quine problem without main(), and loops are also forbidden.
Without loop, it is easy, but I can't figure out how to write one without main(). Can anyone help me or provide me with a link?
You cannot create a (non-freestanding) C program without a main() function. Thus, creating a quine in C without a main() is impossible in the usual sense.
That said, depending on how you define a quine, you might be able to construct a source file which fails to compile, but for which the compile error (on a certain specific compiler) is the contents of the source file.
First thing its impossible to write program without main function because compiler always starts execution from main() function, without main function linker will not be aware of start of data segment.
Yeah but playing with some tricks with preprocessor you can do it, but this is not a good method to do that.
http://www.gohacking.com/2008/03/c-program-without-main-function.html
This might help you.
Take a look here too:
Is a main() required for a C program?
#include <stdio.h>
int
foo(void) {
printf("pong!\n");
return 0;
}
int main() __attribute__((weak, alias("foo")));
There is main() declaration, but not definition.