How to use runtime tracing in OpenMP LLVM? - c

I want to enable runtime tracing and see the output. Something like the output of
KD_TRACE(10, ( buff, gtid, schedule, chunk, lb, ub, st ) );
in kmp_dispatch.cpp
Refer this
https://elixir.bootlin.com/llvm/latest/source/openmp/runtime/src/kmp_dispatch.cpp#L624
So, far I have followed the following tutorial:
https://passlab.github.io/CSE436536/Assignments/project_dev_setup.html
But I am not able to see any output from the tracer.
Is there a particular file or something where the output is logged? Or it is logged in the terminal?
I am compiling the openMP program like this:
clang omp1.c -L/PATH/llvm_work/openmp/BUILD/runtime/src -o omp1
ldd omp1
This is the output:
linux-vdso.so.1 (0x00007ffdae305000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fca2f3bb000)
/lib64/ld-linux-x86-64.so.2 (0x00007fca2f7ac000)
I hope this is using the OpenMP I have build from source and not libomp.
omp1.c:
#include<stdio.h>
#include "omp.h"
int main()
{
int i=0;
#pragma omp parallel for schedule(static)
for(i=0;i<1000;++i)
{
int x = 4+i;
}
}
But when I am trying to run this program using the same command I am getting an error.
/tmp/omp2-d969a9.o: In function `main':
omp2.c:(.text+0x1c8): undefined reference to omp_set_num_threads
clang-11: error: linker command failed with exit code 1 (use -v to see invocation)
Can anyone help me with correctly compiling the openMP programs with the openMP code I have built from source and also in using tracer?
Thank you.

You need to compile with -fopenmp flag. Also, you need to have the debug version of the runtime (built with debug info) + set the environment variable export KMP_DEBUG=511.

I think you have to tell the compiler, that you want to use OpenMP via -fopenmp:
clang -fopenmp omp1.c -L/PATH/llvm_work/openmp/BUILD/runtime/src -o omp1

Related

Why does the terminal keep returning a zsh parse error no matter my input?

I am incredibly new to the C language: I am trying to run sample C programs from codecademy, such as the hello world command below:
#include <stdio.h>
int main() {
// output a line
printf("Hello World!\n");
}
Bottom line is, every time I try to run any code in my macOS terminal, I always get the following error:
zsh: parse error near `\n'
What can I do to resolve this problem?
c is a language where you need to compile the code you've written. You do that by starting a C compiler and give the file containing your C code as input.
Example:
File: myfirstcprogram.c
#include <stdio.h>
int main(void) {
printf("Hello World!\n");
}
Then at the zsh prompt, invoke the compiler:
cc myfirstcprogram.c -o myfirstcprogram
-o myfirstcprogram is here an argument to the compiler telling it what to call the final program.
cc may be clang or gcc or any other compiler you've got installed if cc isn't already linked to the proper compiler.
When the compilation is done, the executable myfirstcprogram should have been created. You can now run it from your zsh prompt:
./myfirstcprogram
You can run it without recompiling it as many times as you like. Only when you change the source code (myfirstcprogram.c) do you need to compile the program into an executable again.

Resolving symbols colision at build time

I have some symbols collision in a C program, some previous search leads to this objcopy the problem is my workflow is a golang cgo one so I don't deal myself with the .o and .a (I know I could be the goal of my lib is to be used by other people so I can't have a custom golang workflow.).
More info of what I need:
I have a bunch of functions doing various things in my go lib, this code is autogenerated and can't be predicted, they sometimes collide (have the same name) with other function later in the build pipeline, so I would like all the C function in my go lib to be renamed, this can either happend at build time using the standart cgo process (basicaly build each file first with gcc and then link them all up) or after the autogeneration of the code (I guess I could run a preprocessor renaming all the functions and there calls in the source but I weren't able to find one).
What I've tried already :
#pragma extern_prefix
This and this seems very promising but whatever I try I can't get it to works :
// test.c
#include <stdio.h>
#pragma extern_prefix "TestPrefix"
int test() {
printf("Hello, World!\n");
return 0;
}
#pragma extern_prefix ""
int main() {
return test();
}
Shell output :
$ gcc test.c -o test && ./test && nm -an test | grep test
Hello, World!
0000000000000000 a test.c
0000000000001149 T test
Unlike what I expected the test symbol isn't prefixed like I expect (with my understanding the symbol should be TestPrefixtest).

Basic SDL2 app compiles with MinGW-w64 but doesn't run

I'm trying to set up a SDL2 and C development environment on Windows 10 with MinGW-w64.
When trying to run the basic c app with SDL initialization, it compiles without warnings but fails to run afterwards, again without any warnings. Executable just exits.
Here's the source:
#include<SDL2/SDL.h>
int main(int argc, char* argv[]) {
puts("\nmain...\n");
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("\nInit error: %s\n", SDL_GetError());
}
else {
puts("\nSDL init success...");
}
}
... and the makefile:
OBJS = sdl_init.c
EXE_NAME = sdl_init_test
CFLAGS_W = -w -Wl,-subsystem,windows
LFLAGS_W = -lmingw32 -lSDL2main -lSDL2
INCS_W = -IC:\MinGW\devlibs\SDL2-2.0.12\x86_64-w64-mingw32\include
LIBS_W = -LC:\MinGW\devlibs\SDL2-2.0.12\x86_64-w64-mingw32\lib
windows_debug:
gcc $(OBJS) $(INCS_W) $(LIBS_W) $(CFLAGS_W) $(LFLAGS_W) -g -o $(EXE_NAME).exe
... and the weird output from gdb:
Reading symbols from .\sdl_init_test.exe...
(gdb) list main
12 ../../src/mingw-w64-crt/crt/crt0_c.c: No such file or directory.
(gdb) b main
Breakpoint 1 at 0x402e70: file ../../src/mingw-w64-crt/crt/crt0_c.c, line 17.
I'm assuming I'm doing something wrong in the linking phase, but can't pinpoint it exactly.
On Linux, everything compiles, runs and debugs as expected.
Here's a corrected makefile, as answered which will compile and work fine in Windows console:
SRC = sdl_init.c
EXE_NAME = sdl_init_test
CFLAGS_W = -Wall -Wl,-subsystem,console
LFLAGS_W = -lmingw32 -lSDL2main -lSDL2
INCS_W = -IC:\MinGW\devlibs\SDL2-2.0.12\x86_64-w64-mingw32\include
LIBS_W = -LC:\MinGW\devlibs\SDL2-2.0.12\x86_64-w64-mingw32\lib
windows_debug:
gcc $(SRC) $(INCS_W) $(LIBS_W) $(CFLAGS_W) $(LFLAGS_W) -g -o $(EXE_NAME).exe
Aside from startup issue with missing dynamic library, you seem to be mislead (arguably by SDL actually being misleading in that aspect) that your b main in gdb sets breakpoint in your main function. That's not the case as SDL redefines main to SDL_main, so if you have #include "SDL2.h" or something similar and SDL have main wrapper implemented for your operating system - your function gets renamed. Internally main (or wmain, or WinMain, or whatever target system uses as user-defined code entry point) is implemented in SDL2main library that you link with, and it calls SDL_main (your code).
TL;DR use b SDL_main in gdb instead.
Second point is why you don't see output text. That's once again windows specific, basically because you've build "GUI" app, which is different from "console" app, and don't really have its stdout associated with console output. Output is still there but you can't see it - but it can be redirected to other program or file, e.g. your_program.exe | more or your_program.exe > stdout.txt. There are ways to reconnect stdout to console (some freopen with CON magic, as I recall), or you can just build console program instead with -Wl,-subsystem,console.
As a side note, -w compiler flag (that could be loosely read as "don't ever warn me about any potential problems with my code as I'm 100% sure it is absolutely perfect and all your warnings are unjustified complaints about my perfect code" (sorry)) is a really really bad idea, with some very rare exceptions. Compilers, especially gcc and clang, are very good at giving warnings in places where it really matter, allowing you to spot mistakes early. You want more warnings (e.g. -Wall -Wextra, probably more), not no warnings at all. And while we're at it, OBJS in makefile logically should mean object files, not sources (of course you technically can call your variables anything you like, it is just misleading).

Getting OpenMP running in Code::Blocks

I am trying to teach myself OpenMP using Windows 7, but I am having a hard time getting Code::Blocks to compile a basic hello world program:
#include <omp.h>
#include <stdio.h>
int main()
{
#pragma omp parallel
printf("Hello from thread %d, nthreads %d\n", omp_get_thread_num(), omp_get_num_threads());
}
I have made some progress, but there is one remaining persistent error that I can't get rid of.
I have -fopenmp in my compiler "Compiler->Compiler Settings->Other Options"
I have -gomp and -pthreads in "Compiler->Linker Settings->Other linker options"
I have C:\Program File (x86)\Codeblocks\MinGW\gcc\mingw32\bin in "Compiler->Toolchain exectuable->Additional Paths"
When I compile, I get the error: "ld.exe: cannot find -lpthread"
Can someone suggest what I might have set up wrong?
Thanks!
The linker complains about a missing library. pthreads is the library that implements the threading interface that your OpenMP implementation uses to do all the threading stuff.
The library is called "libpthread.a" (static version) and "libpthread.so" (dynamic version) on the disk. Try to find these two on the file system under your MinGW directory. They likely reside in a directory called "lib" or "lib64". If either one is missing, then you might need to install an additional package.
Cheers,
-michael

Combine C and TCL using Swig

I have been following a tutorial to combine C with TCL using Swig. The tutorial seemed to be properly working but at the end I ran into an error that I cannot solve. The situation is as follows:
The tutorial I was following is:
http://www.swig.org/tutorial.html.
I have a file named test.c:
char *HelloWorld()
{
return "hello world";
}
and another named test.i:
%module test
%{
/* Put header files here or function declarations like below */
extern char *HelloWorld();
%}
extern char *HelloWorld();
I then used the following command line arguments to ready the correct files:
gcc -c test.c -o test.o
swig -tcl test.i
gcc -c test_wrap.c -o test_wrap.o
gcc -dynamiclib -framework Tcl test.o test_wrap.o -o test.so
And finally I tried to load it using:
tclsh
% load test.so test
This is the point where I received the following error:
dlsym(0x100600090, Test_Unload): symbol not founddlsym(0x100600090, Test_SafeUnload): symbol not found
As far as I know I did not stray from the tutorial. Can anyone tell me how it is that I got this error and more importantly how to get rid of it?
Thanks in advance!
Are those error messages stopping the load from working? They shouldn't; they're reporting that the low-level API for supporting unloading of the extension isn't present, but that's OK (lots of extensions can't be unloaded; it's tricky to write code that supports it).
You don't mention exactly which version of Tcl you are using — but it must be at least 8.5 for those symbols to be even searched for in the first place — so it is a little hard to guess what the exact underlying issue is. (The message should simply not be reported.) I advise filing a bug report on this; make sure you include all exact versions in your report.
It's a long time since I used SWIG, so I'm not sure whether it gives you sufficient control over the code it generates for you to be able to apply this fix. Glossing over that detail, I can reproduce (and fix) the issue with the following:
In 'ext.c':
#include <tcl.h>
int DLLEXPORT Ext_Init(Tcl_Interp *interp) {
if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
return TCL_ERROR;
}
if (Tcl_PkgProvide(interp, "Ext", "0.0") == TCL_ERROR) {
return TCL_ERROR;
}
return TCL_OK;
}
Build, run tclsh, load extension:
$ gcc -dynamiclib -framework Tcl ext.c -o ext.so
$ tclsh8.5
% load ./ext.so
dlsym(0x400000, Ext_SafeInit): symbol not found
dlsym(0x400000, Ext_Unload): symbol not found
dlsym(0x400000, Ext_SafeUnload): symbol not found
Something internal to the library loading code is putting that error message into the interpreters result. To stop the message ever surfacing, set or reset the result so that the _Init() function ends with one or other of:
// Set the result to a message of your choosing
Tcl_SetObjResult(interp, Tcl_NewStringObj("ok", -1));
// Or clear out the result altogether
Tcl_ResetResult(interp);
return TCL_OK;
}
The init block feature of swig might insert code in the right place to achieve the same thing:
%init %{
Tcl_ResetResult(interp);
%}

Resources