Segfault on very simple source - c

I'm trying to write a simple script using the FreeType library. The segfault is occurring during execution of the FT_Set_Pixel_Sizes method, though I'm using it correctly. Any help would be great. Here's the full code:
#include <ft2build.h>
#include FT_FREETYPE_H
main() {
FT_Library library;
FT_Face face;
FT_GlyphSlot slot;
FT_UInt glyph_index = 30;
char* font_file = "/usr/share/fonts/truetype/freefont/FreeMono.ttf";
// Render font
FT_New_Face(library, font_file, 0, &face);
FT_Set_Pixel_Sizes(face, 0, 16); /* THIS LINE IS CAUSING THE SEGFAULT */
slot = face->glyph;
FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
}

You did not initialize your Library variable : see FT_LIBRARY documentation. You should use FT_Init_FreeType :
FT_Init_FreeType
Defined in FT_FREETYPE_H (freetype/freetype.h).
FT_EXPORT( FT_Error ) FT_Init_FreeType( FT_Library *alibrary );
Initialize a new FreeType library object. The set of modules that are
registered by this function is determined at build time.
output alibrary A handle to a new library object.
return FreeType error code. 0 means success.
You could first get used to this library following this tutorial. Take care to check the return values too ...

You have not initialized your library.
FT_Library library;
error = FT_Init_FreeType(&library);
if (error) { /* report error and exit */ }
You also have to check return values of functions like shown above. For instance, FT_New_Face returns an error (as it probably does in your case), you must not access face because it is left in an undefined state.

Related

Plotting pixels to the screen using a physical Framebuffer (UEFI/GOP)

I’ve been recently getting into OS development (completely from scratch), and I’m stuck on an issue where plotting pixels to the screen does not seem to work at all.
For reference, I’m using EDK2 for the UEFI utilities and compiling my bootloader using its build system.
I obtain the framebuffer from the GOP handle after setting my wanted mode (which should be 1366x768, BGRA colour format), but writing any value to the framebuffer memory space seems to not translate anything to the screen. Here are the projects (bootloader and OS) for references:
* OS: https://github.com/kernel-dev/kernelOS
* Bootloader: https://github.com/kernel-dev/kernelOSBootloader
Furthermore, here are the relevant snippets of code that should work, but don’t:
* Function declarations: https://github.com/kernel-dev/kernelOS/blob/main/src/Kernel/Graphics/KernGraphics.c
* Calling the function for clearing the screen: https://github.com/kernel-dev/kernelOS/blob/main/src/Kernel/Kernel.c
Solved
The reason why it wasn't working is because I wasn't properly getting the passed down arguments in my kernel.
This is how it looked like:
// Entry point for kernel
VOID
KernMain (
IN EFI_RUNTIME_SERVICES *RT,
IN EFI_KERN_MEMORY_MAP *MemoryMap,
IN ACPI_DIFFERENTIATED_SYSTEM_DESCRIPTOR_TABLE *Dsdt,
IN KERN_FRAMEBUFFER *Framebuffer)
{
ScreenClearTerminal (Framebuffer);
//
// Should never reach here.
// Will be removed later.
//
while (TRUE) {};
}
However, the way I actually pass them down is like this:
//
// Prepare the arguments to be passed down.
//
LoaderBlock->MemoryMap = &MemoryMap;
LoaderBlock->Dsdt = Dsdt;
LoaderBlock->RT = SystemTable->RuntimeServices;
LoaderBlock->Framebuffer = FB;
//
// Exit boot services.
//
/* ... */
//
// Locate the EP function and call it with the arguments.
//
typedef void (__attribute__((ms_abi)) *EntryPointFunction) (LOADER_PARAMS *LP);
EntryPointFunction EntryPointPlaceholder = (EntryPointFunction) (BaseAddress + EntryPoint);
EntryPointPlaceholder (LoaderBlock);
It's contained inside of a struct. So the appropriate way to obtain them would be like this:
/**
A structure used to "contain" all
the parameters to be passed down
to the kernel's EP.
**/
typedef struct {
EFI_RUNTIME_SERVICES *RT; /// Pointer to the runtime services.
EFI_KERN_MEMORY_MAP *MemoryMap; /// Pointer to the EFI_KERN_MEMORY_MAP.
ACPI_DIFFERENTIATED_SYSTEM_DESCRIPTOR_TABLE **Dsdt; /// Pointer to the DSDT pointer.
KERN_FRAMEBUFFER *Framebuffer; /// Pointer to the KERN_FRAMEBUFFER.
} LOADER_PARAMS;
// Entry point for kernel
VOID
KernMain (
LOADER_PARAMS *LP)
{
ScreenClearTerminal (LP->Framebuffer);
//
// Should never reach here.
// Will be removed later.
//
while (TRUE) {};
}
or, alternatively keeping the old method, but alternating the way they're passed down:
//
// Locate the EP function and call it with the arguments.
//
typedef void (__attribute__((ms_abi)) *EntryPointFunction) (
EFI_RUNTIME_SERVICES *RT,
EFI_KERN_MEMORY_MAP *MemoryMap,
ACPI_DIFFERENTIATED_SYSTEM_DESCRIPTOR_TABLE **Dsdt,
KERN_FRAMEBUFFER *Framebuffer
);
EntryPointFunction EntryPointPlaceholder = (EntryPointFunction) (BaseAddress + EntryPoint);
EntryPointPlaceholder (
SystemTable->RuntimeServices,
&MemoryMap,
Dsdt,
FB);
Completely my bad lol.
Thank you to #user123 and #Dave S for helping me.

How to do automatic OpenGL error checking using GLEW?

I was recently trying to implement automatic error checking after each OpenGL function call. I considered wrapping each OpenGL function in a caller like this:
CheckForErrors(glCreateBuffers(1, &VBO));
But I saw that GLEW already uses its own function wrapper:
#define GLEW_GET_FUN(x) x
So I decided to edit it instead of writting my own function wrapper:
#ifndef GLEW_GET_FUN
#ifdef DEBUG
#define GLEW_GET_FUN(x) while (glGetError() != GL_NO_ERROR);\
x; {\
GLenum error = glGetError();\
if (error != GL_NO_ERROR) {\
printf("[GLEW]: OpenGL error(s) occured while calling %s in %s (line %s):", #x, __FILE__, __LINE__);\
do printf(" %d", error); while (error = glGetError());\
printf("\n");\
__debugbreak();\
}
#else
#define GLEW_GET_FUN(x) x
#endif
#endif
Unfortunately, this doesn't compile. For example this function call:
GLuint vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
Gets changed to this by the preprocessor:
GLuint vertexShaderID = while (glGetError() != GL_NO_ERROR); __glewCreateShader; { GLenum error = glGetError(); if (error != 0) { printf("[GLEW]: OpenGL error(s) occured while calling %s in %s (line %s):", "__glewCreateShader", "main.cpp", 51); do printf(" %d", error); while (error = glGetError()); printf("\n"); __debugbreak(); }(GL_VERTEX_SHADER);
There are 2 problems here:
The statement starts with a while loop, so it cannot return the value.
The parentheses with function parameters are placed after the whole thing and not right after the function call.
I don't know how to overcome those problems and I will appreciate help.
Notes
I am aware of the glDebugMessageCallback() function, but it is only availble in OpenGL 4.3+ which is a rather new and partially insupported yet version.
I cannot remove the while loop at the beginning, because I have to clear all errors before calling the function (unless there is a diffrent way to do this).
I am trying to do something like this, but without using a separate function wrapper.
I don't know how to overcome those problems
You can't. What you want to do is simply not viable in the way you want to do it. You cannot turn an expression (which is what a function call is) into a statement (or rather, a series of statements) and have that work everywhere. It will only work in circumstances where the expression is used as a statement.
If you are unwilling to just regularly insert error checking code into your application, and are unable to use the modern debug messaging API, then the standard solution is to use an external tool to find and report errors. RenderDoc can detect OpenGL errors, for example. It allows you to log every OpenGL call and can report errors anytime they occur.
As Nicol Bolas said, it is impossible to do it the way I originally wanted, but I will describe why this is the case and what can be done instead.
The Problem
GLEW wraps only the name of the function with GLEW_GET_FUN(), so function parameters will always be placed after the end of the define as they are not included in it:
//In code:
glGenBuffers(1, &VBO);
//After preprocessing:
{stuff generated by GLEW_GET_FUN}(1, &VBO);
Preprocessing isn't very inteligent so it will just put the function parameters at the end.
Other Solutions
As described in the question, one could use glDebugMessageCallback() if availble.
Wrap each function with a custom wrapper. Not automatic at all, but if someone is interested here is a great tutorial on how to make one.

How to create OpenCL context based on the openGL context on mac os x

I am creating a project about particle system on mac os x. I found similar questions on Internet, and my question is the same as How can I create an shared context between OpenGL and OpenCL with glfw3 on OSX?
,but I still haven't solved my problem yet. Please help me, thank you.
This is a part of my code:
CGLContextObj glContext = CGLGetCurrentContext();
CGLShareGroupObj shareGroup = CGLGetShareGroup(glContext);
cl_context_properties props[] =
{
CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
(cl_context_properties)kCGLShareGroup,`
0
};
my error messages are :
particles.cpp:522:2: error: ‘CGLContextObj’ was not declared in this scope
CGLContextObj glContext = CGLGetCurrentContext();
particles.cpp:523:2: error: ‘CGLShareGroupObj’ was not declared in this scope
CGLShareGroupObj shareGroup = CGLGetShareGroup(glContext);
particles.cpp:527:2: error: ‘CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE’ was not declared in this scope
CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE,
particles.cpp:528:25: error: ‘kCGLShareGroup’ was not declared in this scope (cl_context_properties)kCGLShareGroup,0
What header files do you include? Location of symbols in header files:
#include <OpenCL/cl_gl_ext.h> for CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE
#include <OpenGL/CGLDevice.h> for CGLGetShareGroup()
#include <OpenGL/CGLCurrent.h> for CGLGetCurrentContext()
Although you could include the header files above, I find it more convenient to just include the following 2 header files:
#include <OpenCL/opencl.h>
#include <OpenGL/OpenGL.h>
Example code:
CGLContextObj gl_ctx = CGLGetCurrentContext();
CGLShareGroupObj gl_sharegroup = CGLGetShareGroup(gl_ctx);
cl_context default_ctx;
cl_context_properties properties[] = {
CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties) gl_sharegroup,
0
};
cl_int err_code;
default_ctx = clCreateContext( properties,
1,
&device, /* cl_device */
[](const char* errinfo, const void* private_info, size_t cb, void* user_data) -> void {
/* context-creation and runtime error handler */
cout << "Context error: " << errinfo << endl;
}, /* C++11, this parameter can be nullptr */
nullptr /*user_data*/,
&err_code);

undefined reference to function that is already defined

Currently trying to build a project in eclipse. The project explorer is shown below:
In cabbie.c I get the error, undefined reference to initialize..., in the code below:
#include <stdio.h>
#include <stdlib.h>
#include "../iotfclient.h"
Iotfclient client;
int rc;
int main() {
/* Setup your example here, code that should run once
*/
rc = initialize(&client, "h7dzt2", "Edison_cabquam", "notwindows95", "token", "Over_9000");
/* Code in this loop will run repeatedly
*/
for (;;) {
}
return 0;
}
The function is already defined in iotfclient.h which was included as a header file. Is it correct to define it as ../iotfclient.h? Am I supposed to make a Makefile? The function prototype in iotfclient.h is given below:
int initialize(Iotfclient *client, char *orgId, char *deviceType, char *deviceId, char *authmethod, char *authtoken);
/**
* Function used to initialize the IBM Watson IoT client using the config file which is generated when you register your device
* #param client - Reference to the Iotfclient
* #param configFilePath - File path to the configuration file
*
* #return int return code
* error codes
* CONFIG_FILE_ERROR -3 - Config file not present or not in right format
*/
This project is trying to connect the bluemix IOT Platform.
initialize() is declared in iotfclient.h. However, it's not necessary defined. In other words, the compiler knows identifier initialise stands for a function, but to create a program, you have also to tell the linker how the function works, that is, add the function body.
Try including ../iotfclient.c.
The function initialize is declared in ../iotfclient.h, it might be defined in ../iotfclient.c, but do you compile this file and link it to your project?

reading the 'return' value of mruby program via C

I am facing an issue with calling of mruby VM in C. I could invoke the mruby vm and execute the ruby code from C. I could also trigger the methods defined in the ruby code as well. But I am facing issue while trying to read the return value of the ruby method. I have provided my example scenario below.
CODE:
#include <stdlib.h>
#include <stdio.h>
#include <mruby.h>
#include <mruby/compile.h>
int main(void)
{
mrb_state *mrb = mrb_open();
char code[] = "def helloworld() return'OK' end";
printf("Executing Ruby code from C!\n");
mrb_load_string(mrb, code);
mrb_load_string(mrb, "helloworld()");
// How to read the return value?
return 0;
}
I am not sure if this is the right way of calling the ruby methods? I couldnt find any documentation or examples on the web. Anyone who tried calling ruby code via c (using mruby) can you please help me?
Regards,
The return value of mrb_load_string() is the value of the last evaluated expression. But it's also mrb_undef_value() on failure that happened during parsing or code generation like a syntax error. In general the exc member of mrb_state is non-null if there was an uncaught exception:
mrb_value rv = mrb_load_string(mrb, "helloworld()");
if (mrb->exc) { // if uncaught exception …
if (!mrb_undef_p(rv)) { // … during execution/run-time
mrb_print_error(mrb); // write backtrace and other details to stderr
}
}
else {
mrb_p(mrb, rv); // similar to Kernel#p
}
If you only want to call a method, the mrb_funcall() family of functions can be used:
mrb_value rv = mrb_funcall(mrb, mrb_top_self(mrb), "helloworld", 0);
Or:
mrb_value rv = mrb_funcall_argv(mrb, mrb_top_self(mrb), mrb_intern_cstr(mrb, "helloworld"), 0, NULL);
Then the parser and code generator won't be used, thus it'll be faster and unless they're used elsewhere, the executable or (shared) library will be much smaller too. Plus mrb_undef_value() isn't a possible return value, otherwise checking for an uncaught exception and retrieving the return value can be done in the same way.

Resources