Showing posts with label c. Show all posts
Showing posts with label c. Show all posts

Saturday, October 13, 2018

GLFW has long delay when creating a window

Leave a Comment

I'm using GLFW for the first time. Pulled the latest stable release (3.2.1) and I'm using the example code found on the GLFW website:

#include <GLFW/glfw3.h>  int main(void) {     GLFWwindow* window;      /* Initialize the library */     if (!glfwInit())         return -1;      /* Create a windowed mode window and its OpenGL context */     window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);     if (!window)     {         glfwTerminate();         return -1;     }      /* Make the window's context current */     glfwMakeContextCurrent(window);      /* Loop until the user closes the window */     while (!glfwWindowShouldClose(window))     {         /* Render here */         glClear(GL_COLOR_BUFFER_BIT);          /* Swap front and back buffers */         glfwSwapBuffers(window);          /* Poll for and process events */         glfwPollEvents();     }      glfwTerminate();     return 0; } 

There's a fairly long delay (20 seconds or so) on the call to choosePixelFormat() (wgl_context.c) - nativeCount has a value of 627 and it seems to just take a long time in the for loop.

There's no delay if I use freeGLUT to create a window or if I just create a window directly with WinAPI calls (CreateWindow, etc) and set up the PFD myself.

I'm using Windows 10, tried it first with Visual Studio 2015 and then in 2017. Graphics card is NVidia Quadro M6000.

I did slightly modify the above code to add a call to initialize glew, but having this call or not did not change the delay.

0 Answers

Read More

Monday, September 17, 2018

PHP internals - what error logging function to use?

Leave a Comment

I'm writing a PHP extension (although its starting to look a lot like a zend extension). There are instances where it needs to write to a logging interface.

I see that zend_error() is being used elsewhere however:

  • reading the source code on github I found zend_error declared in zend/zend.h but I couldn't find the corresponding definition of the function

  • looking at the contexts in which zend_error is used, I suspect that calls will be rerouted/diverted by set_error_handler

Normally, the logging will happen in MINIT and MSHUTDOWN (where presumably an error handler defined by a script cannot have any influence) but there may be times in between as well - and I'm looking for some consistency. Hence trying to understand how the mechanism works.

Is it safe to use zend_error() in MINIT/MSHUTDOWN?

How do I ensure that I am always calling the the default error handler?

1 Answers

Answers 1

Well, I found this in the PHP Wiki. I think this is old, but I imagine it still applies to Zend3:

Don't use zend_error

zend_error() should only be used inside the engine. Inside PHP extensions only PHP's error functions shoudl be used. Typically php_error_docref() is the best choice. php_error_docref() will extend the error message by extra information, like the current function name and properly escape output where needed. zend_error() is used by the Zend Engine due to PHP's modular architecture where the Zend Engine and TSRM should be compilable without other parts of PHP. The engine therefore can not use PHP level APIs. This limitation does not exist in extensions.

What this says to me is that zend_error was written for use in the engine and not designed as one of the tools for use in building extensions. For that reason, you are unlikely to find documentation covering the details you are asking about, and, even if it DOES work reliably for you, it may not continue to do so.

Read More

Tuesday, September 4, 2018

concurrent I/O - buffers corruption, block device driver

Leave a Comment

I developing block layered device driver. So, I intercept WRITE request and encrypt data, and decrypt data in the end_bio() routine (during processing and READ request). So all works fine in single stream. But I getting buffers content corruption if have tried to performs I/O from two and more processes simultaneously. I have not any local storage for buffers.

Do I'm need to count a BIO merging in my driver?

Is the Linux I/O subsystem have some requirements related to the a number of concurrent I/O request?

Is there some tips and tricks related stack using or compilation?

This is under kernel 4.15.

At the time I use next constriction to run over disk sectors:

    /*      * A portion of the bio_copy_data() ...      */     for (vcnt = 0, src_iter = src->bi_iter; ; vcnt++)         {         if ( !src_iter.bi_size)             {             if ( !(src = src->bi_next) )                 break;              src_iter = src->bi_iter;             }          src_bv = bio_iter_iovec(src, src_iter);          src_p = bv_page = kmap_atomic(src_bv.bv_page);         src_p += src_bv.bv_offset;          nlbn    = src_bv.bv_len512;         for ( ; nlbn--; lbn++ , src_p += 512 )                 {                 {                 /* Simulate a processing of data in the I/O buffer */                char *srcp = src_p, *dstp = src_p;                int  count = DUDRV$K_SECTORSZ;                 while ( count--)                 {                 *(dstp++) = ~ (*(srcp++));                 }                  }                 }         kunmap_atomic(bv_page);         **bio_advance_iter**(src, &src_iter, src_bv.bv_len);         } 

Is this correct ? Or I'm need to use something like **bio_for_each_segment(bvl, bio, iter) ** ?

1 Answers

Answers 1

Have you considered the use of vmap with global synchronization, instead?

The use of kmap_atomic has some restrictions:

Since the mapping is restricted to the CPU that issued it, it performs well, but the issuing task is therefore required to stay on that CPU until it has finished, lest some other task displace its mappings.

kmap_atomic() may also be used by interrupt contexts, since it is does not sleep and the caller may not sleep until after kunmap_atomic() is called.

Reference: https://www.kernel.org/doc/Documentation/vm/highmem.txt

Read More

Thursday, July 12, 2018

Linux PCI Driver Setup and Teardown

Leave a Comment

After looking at the kernel docs here: https://www.kernel.org/doc/Documentation/PCI/pci.txt I am lost as to the ordering of function calls to set up and tear down a PCI driver.

I have two questions:

  1. For setup, does pci_enable_device() always come before pci_request_regions()? The documentation seems to point to this fact, but does state:

    OS BUG: we don't check resource allocations before enabling those resources. The sequence would make more sense if we called pci_request_resources() before calling pci_enable_device(). Currently, the device drivers can't detect the bug when when two devices have been allocated the same range. This is not a common problem and unlikely to get fixed soon. This has been discussed before but not changed as of 2.6.19: http://lkml.org/lkml/2006/3/2/194

    However, after doing a quick look through of the source code of several drivers, the consensus is that pci_enable_device() always comes first. Which one of these calls is supposed to come first and why?

  2. For tearing down the driver, I get even more confused. Assuming pci_enable_device() comes first, I would expect that you first call pci_release_regions() prior to calling pci_disable_device() (i.e., following some symmetry). However, the kernel docs say that pci_release_regions() should come last. What makes matters more complicated is that I looked at many drivers and almost all of them had pci_release_regions() before pci_disable_device(), like I would expect. However, I then stumbled across this driver: https://elixir.bootlin.com/linux/v4.12/source/drivers/infiniband/hw/hfi1/pcie.c (code is reproduced below).

    void hfi1_pcie_cleanup(struct pci_dev *pdev) {     pci_disable_device(pdev);     /*      * Release regions should be called after the disable. OK to      * call if request regions has not been called or failed.      */     pci_release_regions(pdev); } 

    Which function is supposed to come first when tearing down the driver? It seems that drivers in the kernel itself can't agree.

1 Answers

Answers 1

The statement that gives a final say is as follows :

o wake up the device if it was in suspended state,

o allocate I/O and memory regions of the device (if BIOS did not),

o allocate an IRQ (if BIOS did not).

So, it makes no sense to ask kernel to reserve resource if there is none. In most cases when we do not need to allocate the resource because it has been done by bios, in those cases we can keep either function first but do only if you are absolutely sure.

Read More

Sunday, July 8, 2018

Is it possible for a thread that is not the UI thread to manipulate the UI elements?

Leave a Comment

I have read that only the UI thread should be allowed to manipulate the UI elements in WinAPI. But I don't think that it is even possible for a thread that is not the UI thread to manipulate the UI elements.

I think that because when a thread (that is not the UI thread) calls the SendMessage() function to manipulate some UI element, a message will be sent to the UI thread, and then it is the UI thread that will manipulate the UI element and not the other thread.

Am I correct?

1 Answers

Answers 1

First, hypothetically speaking in an attempt to satisfy the OP's curiosity:

  • If we define manipulating UI elements as reading from or writing to elements' properties, then technically you could come up with your own UI framework that would maintain the elements independently from the Windows API. Such attempts have been made. WPF is one of them. You could then theoretically make the framework thread-safe and make it possible to access the elements' properties from multiple threads.
  • Also, GDI allows access to its objects from multiple threads, so you could potentially draw to your window from multiple threads (ditto for DirectX). WPF for example has a dedicated render thread (or at least it used to). You could also specify a different thread to process input with AttachThreadInput.

However, given the premise of the question that we're sticking to using the standard Windows API for creating and managing the UI, it is safe to say that access to the window is only achieved from within the thread that created it, because SendMessage() will switch to the owner thread. But that's not to say that invoking SendMessage() from multiple threads is a safe or a recommended approach. On the contrary, it is fraught with peril and care would have to be taken to properly synchronize the threads.

For one thing, a typical WndProc() looks like this:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {     ...     switch (message)     {         case WM_MYMSG1:             ...             SendMessage(hWnd, WM_MYMSG2, wParam, lParam);             ...         break;         ...         }     ... } 

So in order to protect your WndProc() so it can be accessed from multiple threads, you would have to make sure to use a reentrant lock, and not a semaphore, for example.

Secondly, if you use a reentrant lock you must make sure that it is only used within WndProc() or even make it specific to a message. Otherwise it is very easy to get into a deadlock:

//Worker thread: void foo ()  {     EnterCriticalSection(&g_cs);     SendMessage(hWnd, WM_MYMSG1, NULL, NULL);     LeaveCriticalSection(&g_cs);  }   //Owner thread: LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {     switch (message)     {         case WM_MYMSG1:         {             EnterCriticalSection(&g_cs); //Deadlock!             ...             LeaveCriticalSection(&g_cs);          }         break;     } } 

Thirdly, you would have to make sure not to invoke any control-yielding functions within your WndProc(); these include but are not limited to: DialogBox(), MessageBox() and GetMessage(). Else you get a deadlock.

Then, consider a multi-window application, with each window's message pump being run in a separate thread. You would have to ensure not to send any messages between the threads in order not to end up with a deadlock:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {     ...     switch (message)     {         case WM_MYMSG1:             ...             SendMessage(hWnd2, WM_MYMSG1, wParam, lParam); //Deadlock!             ...         break;         ...         }     ... } 

You would also have to be very careful with using Windows APIs that implicitly manage the operating system's process-specific locks, and preserve and maintain the proper lock hierarchy. Quite a few User32 functions and many blocking COM calls fall into this category.

Some of these issues may be alleviated by using InSendMessage() and ReplyMessage() (when using SendMessage()) or PostMessage() and its siblings. However then you get into all kinds of control flow issues, because you may want to know that the message was processed before continuing the current thread or processing the next message. So you end up having to implement some kind of a synchronization mechanism anyway, but this becomes increasingly difficult with many pitfalls to avoid.

Problems don't stop with just sending messages between threads either. Changing WndProc() from a different thread can lead to terrible race-condition bugs:

//in UI thread: wpOld = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_WNDPROC); //in another thread: SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)otherWndProc); //back in UI thread: SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)newWndProc); //still in UI thread: LRESULT CALLBACK newWndProc(...) {     CallWindowProc(wpOld, ...); //Wrong wpOld! } 

Also, improperly using DCs from multiple threads can lead to subtle bugs.

These reasons, and others (including performance), may have led the designers of standard API wrappers like MFC and WinForms to simply assume that their APIs will be used in a single-thread context. They don't offer any thread-safety protections and it's up to the user to implement such mechanisms, however the higher level of abstraction makes it even easier to neglect the underlying issues. When such problems arise, usually the answer is: don't use the control from outside the owner thread.

Read More

Sunday, May 6, 2018

Process list from R to C and access it

Leave a Comment

I would like to use a list in C, that i got from R. I realise the question is very similar to this: Passing a data frame from-to R and C using .call(). However, I fail in storing it in a pointer "*target", from where i would further use it.

R:

.Call("processlist", list(c(1,2), c(1,3,2), c(1,5,4,4))) 

and in C:

#include <Rinternals.h> #include <Rdefines.h>  extern "C" {      SEXP processlist(SEXP lst); }  SEXP processlist(SEXP lst){    SEXP vec  = PROTECT(allocVector(VECSXP, 2));    SET_VECTOR_ELT(vec, 0, VECTOR_ELT(c, 0);    SET_VECTOR_ELT(vec, 1, VECTOR_ELT(c, 1);    SET_VECTOR_ELT(vec, 2, VECTOR_ELT(c, 2);     const lngth = 3;    int *target[lnght];     // Here i want to fill "target", but how?    int *preTarget = INTEGER(vec);     // Bad attempts    target[0] = INTEGER(preTarget[0]);    target[0] = INTEGER(vec[0]); } 

Note: C++ is not an Option unfortunately.

Edit: Desired output would be that I can call *target the following way.

target[0][0] --> Returns: 1 target[1][2] --> Returns: 2 target[2][3] --> Returns: 4 

Calling "vec" in that way throws me an error at the moment.

1 Answers

Answers 1

It seems to me that you just want to access the values in the list from the C side. If that's correct, look at the code below.

In d.c:

/* Including some headers to show the results*/ #include <Rinternals.h> #include <Rdefines.h> #include <R.h> #include <stdlib.h> #include <stdio.h> SEXP processlist(SEXP lst){    int i,l = length(lst);    /* You need an array of arrays, so target will be an int** */     int **target = malloc(sizeof(int *)*l);    for (i=0;i<l;i++) {      target[i] = INTEGER(VECTOR_ELT(lst,i));    }    printf("target[0][0]: %d\n",target[0][0]);    printf("target[1][2]: %d\n",target[1][2]);    printf("target[2][3]: %d\n",target[2][3]);    free(target);    return R_NilValue; } 

The important thing to notice is that target has to be an int**, since it is a pointer to an array of pointers.

In d.R (after d.c has been compiled):

dyn.load("d.so") mylist<-list(c(1,2), c(1,3,2), c(1,5,4,4)) #This is very important: by default 1 in R is double.  #You need to coerce every element of the list to integer. mylist<-lapply(mylist,as.integer) .Call("processlist", mylist) 

Note that we need to coerce each element of the list to integer. The above produces:

target[0][0]: 1 target[1][2]: 2 target[2][3]: 4 
Read More

Thursday, March 8, 2018

valid and invalid syntax for representing the size of array during initialisation

Leave a Comment

I'm currently studying c array and is confused about what can and can't be used to represent the size of the array during initialisation.

Am I right to assume

#define SIZE 5  

and

const int SIZE = 5;  

are fundamentally different to one another?

They have their difference and one particular example that confuses me is

#define SIZE 5 int arr[SIZE] = {11, 22, 33, 44, 55};  

is valid syntax, but

const int SIZE = 5; int arr[SIZE] = {11, 22, 33, 44, 55}; 

is not valid syntax. Though interestingly,

const int SIZE = 5; int arr[SIZE]; 

is valid syntax.

What's the logic behind whether a particular syntax is valid or invalid?

3 Answers

Answers 1

The standard explains it 6.7.9p3

The type of the entity to be initialized shall be an array of unknown size or a complete object type that is not a variable length array type.

In the second case it's a VLA but in the first case it is not. After preprocessing it is same as int arr[5] = {..}.

In the VLA case, the compiler doesn't know the size of a VLA when it's defined, so it can't check validity of an initializer. That's why this initialization is not allowed.

By the way, using const doesn't mean that it is a compile time constant - it just means it can't be changed.

Also from 6.7.6.2p4 there is a clear distinction about when it is VLA and when it is not:-

...If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.

Answers 2

Am I right to assume

#define SIZE 5
and
const int SIZE = 5;

are fundamentally different to one another?

Yes, you are right.

#define is simply a[ textual replacement. Basically, the C preprocessor is going a "find and replace" for you during the compilation process (processing stage). Whereas, const qualified object means "the thing stored at this location can't changed" - roughly equivalent to saying it's "read-only".


#define SIZE 5
int arr[SIZE] = {11, 22, 33, 44, 55};

is valid syntax.

This is exactly equivalent to writing:

int arr[5] = {11, 22, 33, 44, 55};  

yourself. The compiler simply does the replacement job for you when you use define.


const int SIZE = 5;

int arr[SIZE] = {11, 22, 33, 44, 55};

is not valid syntax.

It's invalid but the reason could be more than one. If arr has static storage duration (i.e., the object arr is alive throughout the program execution) then it's invalid. Because C requires that the size of an array object with static storage duration to be a constant expression:

If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type.

So, the following program is not valid:

const int SIZE = 5; int arr[SIZE] = {11, 22, 33, 44, 55}; int main(void) { } 

because SIZE doesn't qualify as a "constant expression" in C. Note that this is totally valid in C++ where SIZE qualifies as a constant expression (the two languages differ here).

Another reason is C standard doesn't allow initializing variable-length arrays. If you have the definition inside a function such as:

The type of the entity to be initialized shall be an array of unknown size or a complete object type that is not a variable length array type.

So if you don't have the initializer then it becomes valid:

int main(void) {     const int SIZE = 5;     int arr[SIZE];  /* This is OK */ } 

Similarly, you can do without the const as well:

int main(void) {     int SIZE = 5;     int arr[SIZE]; /* Thi is OK too. */ } 

In both of the above snippets, arr is simply a variable-length array.

Though interestingly,

const int SIZE = 5; int arr[SIZE];

is valid syntax.

It's valid only if it's inside a function (as above) - it's a VLA. But if you make it have static storage duration such as:

const int SIZE = 5; int arr[SIZE]; /* arr has static storage duration just as                  all objects defined at file scope */  int main(void) { } 

it's invalid because as noted above, SIZE is not a "constant expression" in C.

Similarly,

int main(void) {     const int SIZE = 5;     static int arr[SIZE]; /* arr has static storage duration */ } 

is invalid for the same reason, despite arr being inside a function, because arr has static storage duration.


However, if you have:

enum {SIZE = 5}; int arr[SIZE] = {11, 22, 33, 44, 55};  int arr2[SIZE]; /* Valid without initializer too. */  int main() { } 

it's valid. Why? Because enum constants qualify as "constant expressions" in C.

Answers 3

#define SIZE 5 define SIZE an integer constant expression. While const int SIZE = 5; defines SIZE as a variable expression that's value shall not be modified. const qualifier doesn't make it an integer constant expression (in c++ it does so).

Standard says

n1570-§6.7.6.2 (p4):

[...] If the size is an integer constant expression and the element type has a known constant size, the array type is not a variable length array type; otherwise, the array type is a variable length array type. [...]

When you do

#define SIZE 5 int arr[SIZE] = {11, 22, 33, 44, 55};  

it declare arr as an array which is not a variable length array (VLA). While

const int SIZE = 5; int arr[SIZE]; 

declares arr as a variable length array because SIZE is not a integer constant expression, but a variable expression. But same declaration fails with initializer list and that's because there is a restriction on VLA's is they can't be initialized using list intializers.

§6.7.9 (p2 and p3):

No initializer shall attempt to provide a value for an object not contained within the entity being initialized.

The type of the entity to be initialized shall be an array of unknown size or a complete object type that is not a variable length array type.

Read More

Wednesday, March 7, 2018

Run a portable executable in memory - WinApi

Leave a Comment

Here is the code I currently have:

#include <Windows.h>  DWORD run_portable_executable(unsigned char* binary) {     BOOL success;     const DWORD binary_address = (DWORD)binary;     IMAGE_DOS_HEADER* const dos_header = (LPVOID)binary;     IMAGE_NT_HEADERS* const nt_header = (LPVOID)(binary_address + dos_header->e_lfanew);      STARTUPINFOW startup_info;     PROCESS_INFORMATION process_info;      // Zero the structs to ensure valid values.     SecureZeroMemory(&startup_info, sizeof(startup_info));     SecureZeroMemory(&process_info, sizeof(process_info));      WCHAR current_file_path[MAX_PATH];     GetModuleFileNameW(NULL, current_file_path, MAX_PATH);      // Use the current executable as a dummy process to be taken over by the binary.     success = CreateProcessW(current_file_path, NULL, NULL, NULL, FALSE,          CREATE_SUSPENDED, NULL, NULL, &startup_info, &process_info);      if (!success)         goto err;      CONTEXT ctx =      {         .ContextFlags = CONTEXT_FULL     };      success = GetThreadContext(process_info.hThread, &ctx);      if (!success)         goto err;      // The following will occasionally fail because the fixed address of 0x400000 might     // not be available or might not contain enough space.     LPVOID const pe_base = VirtualAllocEx(process_info.hProcess,          (LPVOID)nt_header->OptionalHeader.ImageBase,              nt_header->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE,                  PAGE_EXECUTE_READWRITE);      if (!pe_base)         goto err;      success = WriteProcessMemory(process_info.hProcess, pe_base, binary,         nt_header->OptionalHeader.SizeOfHeaders, NULL);      if (!success)         goto err;      const DWORD pe_base_address = (DWORD)pe_base;     const DWORD end_of_pe_header =          binary_address + dos_header->e_lfanew + sizeof(IMAGE_NT_HEADERS);      for (WORD i = 0; i < nt_header->FileHeader.NumberOfSections; ++i)     {         const DWORD section_offset = i * sizeof(IMAGE_SECTION_HEADER);         const IMAGE_SECTION_HEADER* const section_header =              (LPVOID)(end_of_pe_header + section_offset);          LPVOID const section_base_address =              (LPVOID)(pe_base_address + section_header->VirtualAddress);          LPCVOID const section_binary_buffer =              (LPVOID)(binary_address + section_header->PointerToRawData);          success = WriteProcessMemory(process_info.hProcess, section_base_address,              section_binary_buffer, section_header->SizeOfRawData, NULL);          if (!success)             goto err;     }      // Ebx points to the PEB struct, where the 8 byte offset points to the     // ImageBaseAddress member.     LPVOID const modified_ebx = (LPVOID)(ctx.Ebx + 8);      success = WriteProcessMemory(process_info.hProcess, modified_ebx,          &nt_header->OptionalHeader.ImageBase, sizeof(DWORD), NULL);      if (!success)         goto err;      ctx.Eax = pe_base_address + nt_header->OptionalHeader.AddressOfEntryPoint;      success = SetThreadContext(process_info.hThread, &ctx);      if (!success)         goto err;      success = ResumeThread(process_info.hThread);      if (!success)         goto err;      return 0; err:     return GetLastError(); } 

This will work most of the time. The problem is here:

VirtualAllocEx(process_info.hProcess, (LPVOID)nt_header->OptionalHeader.ImageBase,      nt_header->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE,         PAGE_EXECUTE_READWRITE); 

This will occasionally fail and return the 487 error code. I have found a highly relevant question about this error which explained exactly what was going wrong. This virtual allocation would always happen at the fixed address of 0x400000 (default for executables), but if that address was currently unavailable at the time, it would return the 487 error code (invalid address).

My question is how should I handle this? I cannot simply set the second argument passed into VirtualAllocEx() to NULL as it would not match with the current image. The question I linked suggests using ReBaseImage(), but I do not know how this would be done for a portable executable in memory. The function requires the path to the .exe or .dll to then write the changes made to the image. How could this be done in memory?

Edit: RbMm proposed to relocate the image using LdrProcessRelocationBlock, a function from ntdll.dll which has the following signature:

IMAGE_BASE_RELOCATION* WINAPI LdrProcessRelocationBlock(ULONG_PTR VA, ULONG SizeOfBlock,     PUSHORT NextOffset, LONG_PTR Diff) 

However, I am not sure how this could be used to move the image to rebase the image as the 3rd party documentation of this method is scarce. If anyone is familiar with its usage, an example would be highly appreciated.

0 Answers

Read More

Monday, March 5, 2018

Alert(Level: Fatal, Description: Decode Error) - Forwarding Proxy

Leave a Comment

I'm trying to make a forwarding proxy but I keep getting an

Alert(Level: Fatal, Description: Decode Error) 

after the Client sends...

Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message 

enter image description here

enter image description here

Any ideas as to what I'm doing wrong?

I can't seem to get a grasp on what the error even means. Does it mean the initial encrypted packet by the client fails to be decrypted by the server? If so, then why?

UPDATE 1

I just was looking at the packets and I noticed a significant difference between using my proxy, and not using the proxy.

The DFE key isn't being interpereted with my proxy.

enter image description here

enter image description here

1 Answers

Answers 1

Any ideas as to what I'm doing wrong?

You're not forwarding the exact amount of data that the proxy is supposed to forward.

But I see you're going further now than at the beginning of your question (good !)

You are implementing a proxy which forwards every single byte which it receives, in both ways, and either it sends too much to the server, or not enough. Check your code again for any conditions when you stop reading the input data to forward, be sure you're forwarding exactly everything. Nothing more, nothing less.

RFC 5246, about Decode Error :

decode_error A message could not be decoded because some field was out of the specified range or the length of the message was incorrect. This message is always fatal and should never be observed in communication between proper implementations (except when messages were corrupted in the network).

Read More

Thursday, February 22, 2018

Unable to access own custom global function of shared library in linux from other module in C

Leave a Comment

I have downloaded libgcrypt library source code and added my own customize function inside one particular file.

Although compilation/build process of customized shared library is successful, and both nm and objdump show the customized function is global, it nonetheless shows an error (undefined reference) at linking time.

Here is what I have done:

inside /src/visibility.c file, I have added my custom function,

void __attribute__((visibility("default"))) MyFunction(void) {     printf("This is added just for testing purpose");    } 

build process

./configure --prefix=/usr/local --disable-ld-version-script  sudo make install 

nm and objdump command find this custom function as global inside shared library.

nm /usr/local/lib/libgcrypt.so | grep MyFunction 000000000000fbf0 T MyFunction   objdump -t /usr/local/lib/libgcrypt.so | grep MyFunction 000000000000fbf0 g     F .text  0000000000000013              MyFunction 

Here is my sample code to access my custom function.

//gcrypt_example_test.c #include <stdio.h> #include <gcrypt.h> #include <assert.h>  int main() {     MyFunction();     return 0; }   export LD_RUN_PATH=/usr/local/lib gcc gcrypt_example_test.c -o test -lgcrypt 

/tmp/ccA0qgAB.o: In function `main': gcrypt_example_test.c:(.text+0x3a2): undefined reference to `MyFunction' collect2: error: ld returned 1 exit status

Edit 1:

I tried all possible way to include function prototype declaration inside header file (/src/gcrypt.h) as follows:

   void __attribute__((visibility("default"))) MyFunction(void);    

... or:

    extern void __attribute__((visibility("default"))) MyFunction(void);   

... or:

    extern void   MyFunction(void); 

... or:

    void   MyFunction(void); 

I am still getting the same error (undefined reference) although no build error results in all above cases.

Why is this happening, and what mistake am I making?

Although other global functions which are part of standard shared library and defined inside visibility.c (nm also shows T for those functions) are accessible, why is my customized global function (MyFunction) of the shared library still inaccessible? Thanks!

Any link or explanation to resolve this error will be highly appreciable.

4 Answers

Answers 1

From the GCC documentation (emphasis mine):

Some linkers allow you to specify the path to the library by setting LD_RUN_PATH in your environment when linking.

But, from the GNU ld man page:

   -rpath=dir        Add a directory to the runtime library search path.  This is used        when linking an ELF executable with shared objects.  All -rpath        arguments are concatenated and passed to the runtime linker,        which uses them to locate shared objects at runtime.  The -rpath        option is also used when locating shared objects which are needed        by shared objects explicitly included in the link; see the        description of the -rpath-link option.  If -rpath is not used        when linking an ELF executable, the contents of the environment        variable "LD_RUN_PATH" will be used if it is defined. 

Note that there is no mention at all of the link time library search path.

You need to compile/link with /usr/local/lib in the link time library search path:

gcc gcrypt_example_test.c -o test -L/usr/local/lib -lgcrypt 

Answers 2

most likely cause of the problem:

The header file for the library has not been updated to include the prototype for the new function

Answers 3

I don't understand the reason behind why it is working now, but not before. Anyway, I found the way to make the code working after adding customized function inside standard library. This post may help others in future.

I first locate libgcrypt.so and then remove all versions of libgcrypt.so

locate libgcrypt.so   sudo rm /usr/local/lib/libgcrypt.so  sudo rm /usr/local/lib/libgcrypt.so.20  sudo rm /usr/local/lib/libgcrypt.so.20.2.2 

then I delete the libgcrypt folder (which I had extracted for building library) to start fresh.

Again, I follow these steps

Step 0 : extract libgcrypt source code

Step 1 : add my custom function, inside /src/visibility.c file

void __attribute__((visibility("default"))) MyFunction(void) {     printf("This is added just for testing purpose");    } 

Step 2 : build library

export LD_RUN_PATH=/usr/local/lib ./configure --prefix=/usr/local --disable-ld-version-script sudo make install 

Step 3: Open another terminal to compile

export LD_RUN_PATH=/usr/local/lib gcc gcrypt_example_test.c -o test -lgcrypt 

Step 4 : run

./test This is added just for testing purpose 

This is working fine now as expected.

What I noticed that __attribute__((visibility("default"))) in function definition and --disable-ld-version-script during build process is very important to make the customized function global, elimination of any makes the customized function local inside shared library(.so) file.

Answers 4

Below changes are working at my end

visibility.h

#include <cstdio>  void __attribute__((visibility("default"))) MyFunction(void); 

visibility.cpp

#include "visibility.h"   void MyFunction(void) {     printf("This is added just for testing purpose"); } 

library build command

gcc -shared -o libtest.so -Wall -Werror -fpic -I. visibility.cpp 

test.cpp

#include <stdio.h> #include <gcrypt.h> #include <assert.h> #include "visibility.h"  extern void MyFunction();  int main() {   MyFunction();   return 0; } 

exe build command

gcc test.cpp -o test -I. -L. -ltest -lstdc++ 

My gcc version is 4.4.7

And of-course I did not try and install the lib under /usr/local/lib but kept it local for quick testing.

Read More

Sunday, November 12, 2017

Safely “lend” memory block to another thread in C, assuming no “concurrent access”

Leave a Comment

The problem

I want to allocate memory in one thread, and safely "lend" the pointer to another thread so it can read that memory.

I'm using a high level language that translates to C. The high level language has threads (of unspecified threading API, since it's cross-platform -- see below) and supports standard C multi-threading primitives, like atomic-compare-exchange, but it's not really documented (no usage examples). The constraints of this high-level language are:

  • Each thread executes an event-processing infinite loop.
  • Each thread has it's own local heap, managed by some custom allocator.
  • Each thread has one "input" message queue, that can contain messages from any number of different other threads.
  • The message passing queues are:
    1. For fixed-type messages
    2. Using copying

Now this is impractical for large (don't want the copy) or variable-sized (I think array-size is part of the type) messages. I want to send such messages, and here's the outline of how I want to achieve it:

  • A message (either a request or a reply) can either store the "payload" inline (copied, fixed limit on total values size), or a pointer to data in the sender's heap
  • The message contents (data in sender's heap) is owned by the sending thread (allocate and free)
  • The receiving thread sends an ack to the sending thread when they are done with the message content
  • The "sending" threads must not modify the message contents after sending them, until receiving the (ack).
  • There should never be a concurrent read access on memory being written to, before the writing is done. This should be guaranteed by the message queues work-flow.

I need to know how to ensure that this works without data races. My understanding is that I need to use memory fences, but I'm not entirely sure which one (ATOMIC_RELEASE, ...) and where in the loop (or if I need any at all).


Portability considerations

Because my high-level language needs to be cross-platform, I need the answer to work on:

  • Linux, MacOS, and optionally Android and iOS
    • using pthreads primitives to lock message queues: pthread_mutex_init and pthread_mutex_lock + pthread_mutex_unlock
  • Windows
    • using Critical Section Objects to lock message queues: InitializeCriticalSection, and EnterCriticalSection + LeaveCriticalSection

If it helps, I'm assuming the following architectures:

  • Intel/AMD PC architecture for Windows/Linux/MacOS(?).
  • unknown (ARM?) for iOS and Android

And using the following compilers (you can assume a "recent" version of all of them):

  • MSVC on Windows
  • clang on Linux
  • Xcode On MacOS/iOS
  • CodeWorks for Android on Android

I've only built on Windows so far, but when the app is done, I want to port it to the other platforms with minimal work. Therefore I'm trying to ensure cross-platform compatibility from the start.


Attempted Solution

Here is my assumed work-flow:

  1. Read all the messages from the queue, until it's empty (only block if it was totally empty).
  2. Call some "memory fence" here?
  3. Read the messages contents (target of pointers in messages), and process the messages.
    • If the message is a "request", it can be processed, and new messages buffered as "replies".
    • If the message is a "reply", the message content of the original "request" can be freed (implicit request "ack").
    • If the message is a "reply", and it itself contains a pointer to "reply content" (instead of an "inline reply"), then a "reply-ack" must be sent too.
  4. Call some "memory fence" here?
  5. Send all the buffered messages into the appropriate message queues.

Real code is too large to post. Here is simplified (just enough to show how the shared memory is accessed) pseudocode using a mutex (like the message queues):

static pointer p = null static mutex m = ... static thread_A_buffer = malloc(...)  Thread-A:   do:     // Send pointer to data     int index = findFreeIndex(thread_A_buffer)     // Assume different value (not 42) every time     thread_A_buffer[index] = 42     // Call some "memory fence" here (after writing, before sending)?     lock(m)     p = &(thread_A_buffer[index])     signal()     unlock(m)     // wait for processing     // in reality, would wait for a second signal...     pointer p_a = null     do:       // sleep       lock(m)       p_a = p       unlock(m)     while (p_a != null)     // Free data     thread_A_buffer[index] = 0     freeIndex(thread_A_buffer, index)   while true  Thread-B:   while true:     // wait for data     pointer p_b = null     while (p_b == null)       lock(m)       wait()       p_b = p       unlock(m)     // Call some "memory fence" here (after receiving, before reading)?     // process data     print *p_b     // say we are done     lock(m)     p = null     // in reality, would send a second signal...     unlock(m) 

Would this solution work? Reformulating the question, does Thread-B print "42"? Always, on all considered platforms and OS (pthreads and Windows CS)? Or do I need to add other threading primitives such as memory fences?


Research

I've spent hours looking at many related SO questions, and read some articles, but I'm still not totally sure. Based on @Art comment, I probably don't need to do anything. I believe this is based on this statement from the POSIX standard, 4.12 Memory Synchronization:

[...] using functions that synchronize thread execution and also synchronize memory with respect to other threads. The following functions synchronize memory with respect to other threads.

My problem is that this sentence doesn't clearly specify if they mean "all the accessed memory", or "only the memory accessed between lock and unlock." I have read people arguing for both cases, and even some implying it was written imprecisely on purpose, to give compiler implementers more leeway in their implementation!

Furthermore, this applies to pthreads, but I need to know how it applies to Windows threading as well.

I'll choose any answer that, based on quotes/links from either a standard documentation, or some other highly reliable source, either proves that I don't need fences or shows which fences I need, under the aforementioned platform configurations, at least for the Windows/Linux/MacOS case. If the Windows threads behave like the pthreads in this case, I'd like a link/quote for that too.

The following are some (of the best) related questions/links I read, but the presence of conflicting information causes me to doubt my understanding.

0 Answers

Read More

Tuesday, November 7, 2017

How to enable/disable Windows 10 battery saver in program?

Leave a Comment

I'm writing a small program to save my laptop's battery, and I can now switch between power schemes using PowerSetActiveScheme.

The next step is to control the battery saver in Windows 10. Though I can read the state of it using GetSystemPowerStatus, I can't find a way to enable/disable it programmatically. Are there any functions in Windows API to do this?

3 Answers

Answers 1

Most probably you can do it Linux-way, by calling a system app named PowerCfg through ShellExecuteEx():

powercfg /setdcvalueindex SCHEME_CURRENT SUB_ENERGYSAVER ESBATTTHRESHOLD 100 powercfg /setactive scheme_current 

This means that the energy saver is activated even when the battery percentage equals 100%. SUB_ENERGYSAVER and its sub-GUID ESBATTTHRESHOLD are described here.

Answers 2

You seem to be out of luck. MSDN docs show no API through which the battery saver could be controlled. Examining SettingsHandlers_OneCore_BatterySaver shows that only GetSetting is exposed. Even SetPowerState in WMI Win32_Battery is not implemented -- I know this is not exactly what you need, but it shows that Microsoft has not gotten around to exposing the battery-related functionality. At this point, instead of reverse-engineering the button click, your best bet is probably to emulate it with something like AutoHotKey, however beware of the pitfalls with that.

Answers 3

You can follow this step by step tutorial

Click or tap the “Battery saver” tile to activate or deactivate it.

Read More

Saturday, September 16, 2017

GDB does not step-into functions without step-mode=on

Leave a Comment

I have an executable that is dynamically linked with a .so file, both compiled with debug symbols.

Now when I start the process with a gdb and step over it - the step command does not step into functions (defined in a .so) unless I set the step-mode on.

Sources are available and gdb certainly can find them.

Why is it happening?

Here is the corresponding debug output enabled via set debug infrun 1:

34          assert_se(calendar_spec_from_string(input, &c) >= 0); infrun: infrun_async(0) (gdb) s infrun: clear_proceed_status_thread (Thread 0x7ffff7fb3900 (LWP 7009)) infrun: proceed (addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT) infrun: proceed: resuming Thread 0x7ffff7fb3900 (LWP 7009) infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e0d infrun: infrun_async(1) infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e11 infrun: stepping inside range [0x100000e0d-0x100000e4f] infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e11 infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e15 infrun: stepping inside range [0x100000e0d-0x100000e4f] infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e15 infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e18 infrun: stepping inside range [0x100000e0d-0x100000e4f] infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e18 infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e1b infrun: stepping inside range [0x100000e0d-0x100000e4f] infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e1b infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000c08 infrun: stepped into subroutine infrun: inserting step-resume breakpoint at 0x100000e20 infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000c08 infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e20 infrun: BPSTAT_WHAT_STEP_RESUME infrun: stepping inside range [0x100000e0d-0x100000e4f] infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e20 infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e23 infrun: stepping inside range [0x100000e0d-0x100000e4f] infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e23 infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e26 infrun: stepping inside range [0x100000e0d-0x100000e4f] infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e26 infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e29 infrun: stepping inside range [0x100000e0d-0x100000e4f] infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e29 infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e4f infrun: stepped to a different line infrun: stop_waiting infrun: clear_step_over_info infrun: stop_all_threads infrun: stop_all_threads, pass=0, iterations=0 infrun:   Thread 0x7ffff7fb3900 (LWP 7009) not executing infrun: stop_all_threads, pass=1, iterations=1 infrun:   Thread 0x7ffff7fb3900 (LWP 7009) not executing infrun: stop_all_threads done 36          assert_se(calendar_spec_to_string(c, &p) >= 0); infrun: infrun_async(0) (gdb) s infrun: clear_proceed_status_thread (Thread 0x7ffff7fb3900 (LWP 7009)) infrun: proceed (addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT) infrun: proceed: resuming Thread 0x7ffff7fb3900 (LWP 7009) infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e4f infrun: infrun_async(1) infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e53 infrun: stepping inside range [0x100000e4f-0x100000e91] infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e53 infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   -1.0.0 [process -1], infrun:   status->kind = ignore infrun: TARGET_WAITKIND_IGNORE infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e57 infrun: stepping inside range [0x100000e4f-0x100000e91] infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e57 infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   -1.0.0 [process -1], infrun:   status->kind = ignore infrun: TARGET_WAITKIND_IGNORE infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e5a infrun: stepping inside range [0x100000e4f-0x100000e91] infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e5a infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   -1.0.0 [process -1], infrun:   status->kind = ignore infrun: TARGET_WAITKIND_IGNORE infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e5d infrun: stepping inside range [0x100000e4f-0x100000e91] infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e5d infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   -1.0.0 [process -1], infrun:   status->kind = ignore infrun: TARGET_WAITKIND_IGNORE infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000c48 infrun: stepped into subroutine infrun: inserting step-resume breakpoint at 0x100000e62 infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000c48 infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   -1.0.0 [process -1], infrun:   status->kind = ignore infrun: TARGET_WAITKIND_IGNORE infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e62 infrun: BPSTAT_WHAT_STEP_RESUME infrun: stepping inside range [0x100000e4f-0x100000e91] infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e62 infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   -1.0.0 [process -1], infrun:   status->kind = ignore infrun: TARGET_WAITKIND_IGNORE infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e65 infrun: stepping inside range [0x100000e4f-0x100000e91] infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e65 infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   -1.0.0 [process -1], infrun:   status->kind = ignore infrun: TARGET_WAITKIND_IGNORE infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e68 infrun: stepping inside range [0x100000e4f-0x100000e91] infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e68 infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e6b infrun: stepping inside range [0x100000e4f-0x100000e91] infrun: resume (step=1, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 0x7ffff7fb3900 (LWP 7009)] at 0x100000e6b infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   -1.0.0 [process -1], infrun:   status->kind = ignore infrun: TARGET_WAITKIND_IGNORE infrun: prepare_to_wait infrun: target_wait (-1.0.0, status) = infrun:   7009.7009.0 [Thread 0x7ffff7fb3900 (LWP 7009)], infrun:   status->kind = stopped, signal = GDB_SIGNAL_TRAP infrun: TARGET_WAITKIND_STOPPED infrun: stop_pc = 0x100000e91 infrun: stepped to a different line infrun: stop_waiting infrun: clear_step_over_info infrun: stop_all_threads infrun: stop_all_threads, pass=0, iterations=0 infrun:   Thread 0x7ffff7fb3900 (LWP 7009) not executing infrun: stop_all_threads, pass=1, iterations=1 infrun:   Thread 0x7ffff7fb3900 (LWP 7009) not executing infrun: stop_all_threads done 37          printf("\"%s\" → \"%s\"\n", input, p); infrun: infrun_async(0) 

1 Answers

Answers 1

Seems to be related to "-Wl,-z,now" option to the linker.

man page says:

now - When generating an executable or shared library, mark it to tell the dynamic linker to resolve all symbols when the program is started, or when the shared library is linked to using dlopen, instead of deferring function call resolution to the point when the function is first called.

When you set step-mode on and gebug an executable linked with this option, you may notice that you don't step directly to the function in the shared library, but at first to somewhere like

(gdb) s 0x0000555555554638 in ?? () 

Can't say exactly, what it is.

Read More

Wednesday, August 2, 2017

Conditions under which stepping into shared library should work in gdb?

Leave a Comment

There are many questions related to specific errors why stepping into a shared library with gdb isn't working. None of them provide a systematic answer on how to confirm where the the cause is. This questions is about the ways to diagnose the setup.

Setup example

main.c

#include <stdio.h> #include "myshared.h"  int main(void) {     int a = 3;     print_from_lib();     return 0; } 

myshared.h

void print_from_lib(); 

myshared.c

#include <stdio.h>  void print_from_lib() {     printf("Printed from shared library\n"); } 

Place all the files in the same directory.

export LIBRARY_PATH=$PWD:$LIBRARY_PATH export LD_LIBRARY_PATH=$PWD:$LD_LIBRARY_PATH gcc -ggdb -c -Wall -Werror -fpic myshared.c -o myshared-ggdb.o gcc -ggdb -shared -o libmyshared-ggdb.so myshared-ggdb.o gcc -ggdb main.c -lmyshared-ggdb -o app-ggdb 

Getting the error

$ gdb ./app-ggdb  GNU gdb (Ubuntu 7.12.50.20170314-0ubuntu1) 7.12.50.20170314-git ...### GDB STARTING TEXT Reading symbols from app-ggdb...done. (gdb) break 7 Breakpoint 1 at 0x78f: file main.c, line 7. (gdb) run Starting program: /home/user/share-lib-example/app-ggdb   Breakpoint 1, main () at main.c:7 7       print_from_lib(); (gdb) s Printed from shared library 8       return 0; 

gdb is not stepping inside of the function

Necessary but not sufficient checks

Debug symbols in the binaries

$ objdump --syms libmyshared-ggdb.so | grep debug 0000000000000000 l    d  .debug_aranges 0000000000000000              .debug_aranges 0000000000000000 l    d  .debug_info    0000000000000000              .debug_info 0000000000000000 l    d  .debug_abbrev  0000000000000000              .debug_abbrev 0000000000000000 l    d  .debug_line    0000000000000000              .debug_line 0000000000000000 l    d  .debug_str     0000000000000000              .debug_str 

Symbols recognized by gdb

$ gdb ./app-ggdb ...### GDB STARTING TEXT Reading symbols from app-ggdb...done. (gdb) break 7 Breakpoint 1 at 0x78f: file main.c, line 7. (gdb) run Starting program: /home/user/share-lib-example/app-ggdb   Breakpoint 1, main () at main.c:7 7       print_from_lib(); (gdb)(gdb) info sharedlibrary From                To                  Syms Read   Shared Object Library 0x00007ffff7dd7aa0  0x00007ffff7df55c0  Yes         /lib64/ld-linux-x86-64.so.2 0x00007ffff7bd5580  0x00007ffff7bd5693  Yes         /home/user/share-lib-example/libmyshared-ggdb.so 0x00007ffff782d9c0  0x00007ffff797ed43  Yes         /lib/x86_64-linux-gnu/libc.so.6 

Confirm .gdbinit isn't the cause

~/.gdbinit contains commands automatically executed upon starting gdb. ref.

Running gdb with the -nx flags can exclude .gdbinit as the source of the problem.

Question

Am looking for suggestions to complete the list of Necessary but not sufficient checks.

Update

The exact same steps seem to work in normal debug for user haolee. See answer below.

3 Answers

Answers 1

Your problem is self-imposed: don't do this: set step-mode on, and step will work as you expect.

From the GDB manual:

set step-mode set step-mode on The set step-mode on command causes the step command to stop at the first instruction of a function which contains no debug line information rather than stepping over it.  This is useful in cases where you may be interested in inspecting the machine instructions of a function which has no symbolic info and do not want GDB to automatically skip over this function. 

You are interested in the opposite of the above -- you want to step into the print_from_lib function and avoid stopping inside the PLT jump stub and the dynamic loader's symbol resolution function.

Answers 2

GDB 7.11 can't reproduce this problem. This is my steps. I hope this will help you:

1.gcc -ggdb -c -Wall -Werror -fpic myshared.c -o myshared-ggdb.o 2.gcc -ggdb -shared -o libmyshared-ggdb.so myshared-ggdb.o 3.gcc -ggdb main.c -lmyshared-ggdb -o app-ggdb -L. 4.gdb ./app-ggdb 

In GDB,

(gdb) set env LD_LIBRARY_PATH=. (gdb) b main.c:7 Breakpoint 1 at 0x4006a5: file main.c, line 7. (gdb) r Starting program: /home/haolee/tmp/app-ggdb   Breakpoint 1, main () at main.c:7 7       print_from_lib(); (gdb) s print_from_lib () at myshared.c:5 5       printf("Printed from shared library\n"); (gdb)  

I step into the function print_from_lib successfully.

Answers 3

Some more tests you can do on built shared library:

  1. file libmyshared-ggdb.so should report that library has debug info and not stripped.
  2. nm libmyshared-ggdb.so | grep print_from_lib should find the symbol for print_from_lib function.

If all above tests passed try to load the library directly in gdb and find the function:

gdb libmyshared-ggdb.so (gdb) info functions print_from_lib 

Function print_from_lib name should be printed. If not, something is wrong with gdb or gcc.

Read More

Wednesday, July 12, 2017

Referencing a char* that went out of scope

Leave a Comment

I recently started programming in C again after having programmed in C++ for a while, and my understanding of pointers is a bit rusty.

I would like to ask why this code is not causing any errors:

char* a = NULL; {     char* b = "stackoverflow";     a = b; }  printf(a); 

I thought that because b went out of scope, a should reference a non-existing memory location, and thus their would be a runtime error when calling printf.

I ran this code in MSVC about 20 times, and no errors were shown.

8 Answers

Answers 1

Inside the scope where b is defined, it is assigned the address of a string literal. These literals typically live in a read-only section of memory as opposed to the stack.

When you do a=b you assign the value of b to a, i.e. a now contains the address of a string literal. This address is still valid after b goes out of scope.

If you had taken the address of b and then attempted to dereference that address, then you would invoke undefined behavior.

So your code is valid and does not invoke undefined behavior, but the following does:

int *a = NULL; {     int b = 6;     a = &b; }  printf("b=%d\n", *a); 

Another, more subtle example:

char *a = NULL; {     char b[] = "stackoverflow";     a = b; }  printf(a); 

The difference between this example and yours is that b, which is an array, decays to a pointer to the first element when assigned to a. So in this case a contains the address of a local variable which then goes out of scope.

EDIT:

As a side note, it's bad practice to pass a variable as the first argument of printf, as that can lead to a format string vulnerability. Better to use a string constant as follows:

printf("%s", a); 

Or more simply:

puts(a); 

Answers 2

String literals are statically allocated, so the pointer is valid indefinitely. If you had said char b[] = "stackoverflow", then you would be allocating a char array on the stack that would become invalid when the scope ended. This difference also shows up for modifying strings: char s[] = "foo" stack allocates a string that you can modify, whereas char *s = "foo" only gives you a pointer to a string that can be placed in read-only memory, so modifying it is undefined behaviour.

Answers 3

Line by line, this is what your code does:

char* a = NULL; 

a is a pointer not referencing anything (set to NULL).

{     char* b = "stackoverflow"; 

b is a pointer referencing the static, constant string literal "stackoverflow".

    a = b; 

a is set to also reference the static, constant string literal "stackoverflow".

} 

b is out of scope. But since a is not referencing b, then that does not matter (it's just referencing the same static, constant string literal as b was referencing).

printf(a); 

Prints the static, constant string literal "stackoverflow" referenced by a.

Answers 4

Other people have explained that this code is perfectly valid. This answer is about your expectation that, if the code had been invalid, there would have been a runtime error when calling printf. It isn't necessarily so.

Let's look at this variation on your code, which is invalid:

#include <stdio.h> int main(void) {     int *a;     {         int b = 42;         a = &b;     }     printf("%d\n", *a); // undefined behavior     return 0; } 

This program has undefined behavior, but it happens to be fairly likely that it will, in fact, print 42, for several different reasons — many compilers will leave the stack slot for b allocated for the entire body of main, because nothing else needs the space and minimizing the number of stack adjustments simplifies code generation; even if the compiler did formally deallocate the stack slot, the number 42 probably remains in memory until something else overwrites it, and there's nothing in between a = &b and *a to do that; standard optimizations ("constant and copy propagation") could eliminate both variables and write the last-known value for *a directly into the printf statement (as if you had written printf("%d\n", 42)).

It's absolutely vital to understand that "undefined behavior" does not mean "the program will crash predictably". It means "anything can happen", and anything includes appearing to work as the programmer probably intended (on this computer, with this compiler, today).


As a final note, none of the aggressive debugging tools I have convenient access to (Valgrind, ASan, UBSan) track "auto" variable lifetimes in sufficient detail to trap this error, but GCC 6 does produce this amusing warning:

$ gcc -std=c11 -O2 -W -Wall -pedantic test.c test.c: In function ‘main’: test.c:9:5: warning: ‘b’ is used uninitialized in this function     printf("%d\n", *a); // undefined behavior     ^~~~~~~~~~~~~~~~~~ 

I believe what happened here was, it did the optimization I described above — copying the last known value of b into *a and then into the printf — but its "last known value" for b was a "this variable is uninitialized" sentinel rather than 42. (It then generates code equivalent to printf("%d\n", 0).)

Answers 5

The code doesn't generate any error because you are simply assigning character pointer b to another character pointer a and that is perfectly fine.

In C, You can assign a pointer reference to another pointer. here actually the string "stackoverflow" is used as a literal and the base address location of that string will be assign to a variable.

Though you are out of scope for variable b but still the assignment had been done with the a pointer. So it will print the result without any error.

Answers 6

Step by step execution of given code Please understand that the memory locations 1000, 2000 and 3000 are used just for illustration.

After the end of the scope, the memory is just deallocated for 'b'. But, the memory location is not over written of stored with NULL.

These are called Memory leakages.

Answers 7

String literals are always allocated statically and program can access anytime,

char* a = NULL;  {      char* b = "stackoverflow";      a = b;  }    printf(a);

Here memory to string literal stackoverflow is allocated by compiler same as it allocate memory to int/char variables or pointers

Difference is that string literal are places in READONLY section/segment. Variable b is allocated at stack but it is holding memory address of read only section/segmemt.

In the code var 'b' has address of string literal. Even when b looses its scope the memory for string literal will always be allocated

Note: Memory allocated to string literals is part of binary and will be removed once program is unloaded

Refer ELF binary specification to understand in more details

Answers 8

I think that, as a proof of previous answers, it is good to take a look at what really sits inside your code. People already mentioned that string literals lay inside .text section. So, they (literals) are simply, always, there. You can easily find this for the code

#include <string.h>  int main() {   char* a = 0;   {     char* b = "stackoverflow";     a = c;   }   printf("%s\n", a); } 

using following command

> cc -S main.c 

inside main.s you will find, at the very bottom

... ... ...         .section        __TEXT,__cstring,cstring_literals L_.str:                                 ## @.str         .asciz  "stackoverflow"  L_.str.1:                               ## @.str.1         .asciz  "%s\n" 

You can read more about assembler sections (for example) here: https://docs.oracle.com/cd/E19455-01/806-3773/elf-3/index.html

And here you can find very well prepared coverage of Mach-O executables: https://www.objc.io/issues/6-build-tools/mach-o-executables/

Read More

Wednesday, May 31, 2017

execinfo.h missing when installing xgboost in Cygwin

Leave a Comment

I've follow the following tutorial in order to install xgboost python package within Cygwin64:

https://www.ibm.com/developerworks/community/blogs/jfp/entry/Installing_XGBoost_For_Anaconda_on_Windows

But when executing the make in dmlc-core directory I get the following errors:

harrison4@mypc ~/xgboost/dmlc-core $ mingw32-make -j4 g++ -c -O3 -Wall -Wno-unknown-pragmas -Iinclude  -std=c++0x -fPIC -DDMLC_USE_HDFS=0 -DDMLC_USE_S3=0 -DDMLC_USE_AZURE=0 -msse2 -o line_split.o src/io/line_split.cc g++ -c -O3 -Wall -Wno-unknown-pragmas -Iinclude  -std=c++0x -fPIC -DDMLC_USE_HDFS=0 -DDMLC_USE_S3=0 -DDMLC_USE_AZURE=0 -msse2 -o recordio_split.o src/io/recordio_split.cc g++ -c -O3 -Wall -Wno-unknown-pragmas -Iinclude  -std=c++0x -fPIC -DDMLC_USE_HDFS=0 -DDMLC_USE_S3=0 -DDMLC_USE_AZURE=0 -msse2 -o input_split_base.o src/io/input_split_base.cc g++ -c -O3 -Wall -Wno-unknown-pragmas -Iinclude  -std=c++0x -fPIC -DDMLC_USE_HDFS=0 -DDMLC_USE_S3=0 -DDMLC_USE_AZURE=0 -msse2 -o io.o src/io.cc src/io/line_split.cc:1:0: aviso: se descarta -fPIC para el objetivo (todo el código es independiente de posición)  // Copyright by Contributors  ^ src/io.cc:1:0: aviso: se descarta -fPIC para el objetivo (todo el código es independiente de posición)  // Copyright by Contributors  ^ src/io/input_split_base.cc:1:0: aviso: se descarta -fPIC para el objetivo (todo el código es independiente de posición)  // Copyright by Contributors  ^ src/io/recordio_split.cc:1:0: aviso: se descarta -fPIC para el objetivo (todo el código es independiente de posición)  // Copyright by Contributors  ^ In file included from include/dmlc/io.h:14:0,                  from src/io/line_split.cc:2: include/dmlc/./logging.h:18:22: error fatal: execinfo.h: No such file or directory compilación terminada. Makefile:83: recipe for target 'line_split.o' failed mingw32-make: *** [line_split.o] Error 1 mingw32-make: *** Waiting for unfinished jobs.... In file included from src/io/input_split_base.cc:2:0: include/dmlc/logging.h:18:22: error fatal: execinfo.h: No such file or directory compilación terminada. In file included from include/dmlc/io.h:14:0,                  from src/io.cc:4: include/dmlc/./logging.h:18:22: error fatal: execinfo.h: No such file or directory compilación terminada. Makefile:83: recipe for target 'input_split_base.o' failed mingw32-make: *** [input_split_base.o] Error 1 Makefile:83: recipe for target 'io.o' failed mingw32-make: *** [io.o] Error 1 In file included from include/dmlc/./io.h:14:0,                  from include/dmlc/recordio.h:12,                  from src/io/recordio_split.cc:2: include/dmlc/././logging.h:18:22: error fatal: execinfo.h: No such file or directory compilación terminada. Makefile:83: recipe for target 'recordio_split.o' failed mingw32-make: *** [recordio_split.o] Error 1 

Why am I getting this error? Let me know if you need more information, please.

1 Answers

Answers 1

You can put #undef DMLC_LOG_STACK_TRACE right after it's definition on line 45 here. See example in this gist.

execinfo.h is only available on Linux, but in this project it is used only for debugging and printing stack trace on Linux. There is a check for Mingw in their codebase, don't know why it is not defined (they've disabled it, see this PR).

You should try to change those lines and run make again.

Read More

Monday, May 29, 2017

Syslog not forwarding remote messages

Leave a Comment

I configured /etc/syslog.conf with below configuration

*.* @10.10.10.2:514 *.* @@10.10.10.2:514 

and logged through below code

openlog("Test-Msg", LOG_PID, LOG_LOCAL0); for (int i = 0; i <10; i++) {     syslog(LOG_ALERT, "My msg %d", i);     std::cout<<"-------------Writing Syslog "<<i<<"\n"; }  closelog(); 

but its not forwarding to remote server. instead of that it creates a file "@10.10.10.2:514" & "@@10.10.10.2:514" and logging all the message there.

Tested with wireshark, no messages are forwarded to remote system.

I am using yocto platform and busybox 1.22 syslog implementation.

Update

In yocto I saw one more configuration file /etc/syslog-startup.conf and there I configured

DESTINATION=remote  # log destinations (buffer file remote) REMOTE=10.10.10.2:514          # where to log (syslog remote) 

Now its started forwarding all the messages, but as per the linux manuals syslog conf must support *.=alert @<host:port> filter. If I have to use the above configuration how can I apply the filters?

2 Answers

Answers 1

By default Yocto-based systems use Busybox to provide minimal versions of many basic tools. syslog is one of those tools. This is a quote from Busybox documentation:

Note that this version of syslogd ignores /etc/syslog.conf.

To get full syslog functionality you'd have to include a more complete implementation on your image. There are several options in meta-openembedded, rsyslog in meta-oe is probably a good default choice.

Answers 2

I would first use logger (tool incluided in busybox) to ensure that your syslog configuration is correct. If the messages are sent well by this method, then we can investigate the code.

logger [OPTIONS] [MESSAGE]  Write MESSAGE to the system log. If MESSAGE is omitted, log stdin.  Options:          -s      Log to stderr as well as the system log         -t TAG  Log using the specified tag (defaults to user name)         -p PRIO Priority (numeric or facility.level pair) 
Read More

Wednesday, May 24, 2017

How to create dll of Lua Module

Leave a Comment

I'm trying to write an external Lua module.

I work on Windows 8.1 and I use gcc as compiler.

My requirement is to build/compile everything all by myself without using pre-compiled files available online.

First of all, I build C source code of Lua 5.2.4 as follow:

  1. gcc -c *.c

  2. ren lua.o lua.obj

  3. ren luac.o luac.obj

  4. ar rcs luaX.X.X.lib *.o

  5. gcc -shared -o luaX.X.X.dll *.o

  6. gcc lua.c luaX.X.X.lib -o luaX.X.X.exe

  7. gcc luac.c luaX.X.X.lib -o luacX.X.X.exe

  8. del *.o *.obj

where X.X.X is the source code revision.

Once I created my .exe, I write the C code of my module (let's call it LuaMath):

#include<windows.h> #include<math.h> #include "lauxlib.h" #include "lua.h"   static int IdentityMatrix(lua_State *L) {     int in = lua_gettop(L);     if (in!=1)     {        lua_pushstring(L,"Maximum 1 argument");        lua_error(L);     }     lua_Number n = lua_tonumber(L,1);     lua_newtable(L);                  /*                 tabOUT n */     int i,j;     for (i=1;i<=n;i++)     {         lua_newtable(L);              /*         row(i) tabOUT n */         lua_pushnumber(L,i);          /*       i row(i) tabOUT n */         for (j=1;j<=n;j++)         {             lua_pushnumber(L,j);      /*     j i row(i) tabOUT n */             if (j==i)             {                 lua_pushnumber(L,1);             }             else                      /* 0/1 j i row(i) tabOUT n */             {                 lua_pushnumber(L,0);             }             /*  Put 0/1 inside row(i) at j position */             lua_settable(L,-4);       /*       i row(i) tabOUT n */         }         lua_insert(L,-2);             /*       row(i) i tabOUT n */          /* Insert row(i) into position in tabOUT */         lua_settable(L,2);            /*                tabOUT n */     }     return 1; }   static const struct luaL_Reg LuaMath [] = {{"IdentityMatrix", IdentityMatrix},                                            {            NULL,           NULL}};  int __declspec(dllexport) luaopen_LuaMath(lua_State *L) {     luaL_newlib(L,LuaMath);     return 1; } 

then I compile it linking to dynamic library.dll as follow:

gcc -shared -L "<path where luaX.X.X.dll is>" -l "luaX.X.X" LuaMath.c 

When I call the the module into Lua code as follow:

require("LuaMath") 

the output is:

> require("LuaMath") multiple Lua VMs detected stack traceback:         [C]: in ?         [C]: in function 'require'         stdin:1: in main chunk         [C]: in ? > 

What do I do wrong?

Many thanks in advance.

2 Answers

Answers 1

Do not link the Lua library with your DLL. That's what the error message is telling you.

Answers 2

May be you need define a SYSCFLAGS LUA_BUILD_AS_DLL then compile the lua code again

gcc -DLUA_BUILD_AS_DLL -c *.c 

Why not you use the Makefile which provide by Lua source? It is easy way to complie, if you read the Makefile, it set the gcc flags for you.

cd /path/to/lua-src make mingw 

now you should get lua.exe, luac.exe, lua53.dll in /path/to/lua-src/src/

compile your module

gcc -shared -I/path/to/lua-src/src LuaMath.c -o LuaMath.dll -L/path/to/lua-src/src -llua53 
Read More

Sunday, February 12, 2017

How to update internal state of nginx' module runtime?

Leave a Comment

Lets suppose I wish to write a nginx module that blocks clients by IP. In order to do so, on initialization stage i read a file with IP addresses that I have to block (black list) and store it in module's context.

Now I wish to update the black list without restarting nginx. One of the possible solutions, is to add a handler on specific location. e.g. if uri "/block/1.2.3.4" requested, my handler adds ip address 1.2.3.4 to the black list.

However, nginx runs several workers as separated processes, so only one particular worker will updated.

What is a common pattern to cope such problems?

1 Answers

Answers 1

But nginx does not require a restart (nor any downtime) in order to change the configuration!

See:

In order for nginx to re-read the configuration file, a HUP signal should be sent to the master process. The master process first checks the syntax validity, then tries to apply new configuration, that is, to open log files and new listen sockets. If this fails, it rolls back changes and continues to work with old configuration. If this succeeds, it starts new worker processes, and sends messages to old worker processes requesting them to shut down gracefully. Old worker processes close listen sockets and continue to service old clients. After all clients are serviced, old worker processes are shut down.

As an administrator, it would be my expectation that all modules would, in fact, be controlled in this way, too.

(Of course, if you require a lot of changes to the configuration very often, a different solution might be more appropriate.)


You give an explicit example of blocking access by IP. Are you sure you require a new module in order to accomplish the task? It would seem that a combination of the following standard directives might suffice already:


Read More

Wednesday, September 21, 2016

Unable to Run application via Terminal but application working fine in XCode

1 comment

I am working on lilgp which is a c language based tool for Genetic Programming. The problem that i am facing is that I am using XCode for the project and it is working fine and shows correct output via terminal. But when i try to run the same application in DerivedData of my project in XCode i get segmentation fault (11)

Then i have checked the console in Utilities for errors which shows error like this

    Process:               Theisis [9325] Path:                  /Users/USER/Library/Developer/Xcode/DerivedData/Theisis-gszeehddtmnlkqdbicpeffygvkcw/Build/Products/Release/Theisis Identifier:            Theisis Version:               0 Code Type:             X86-64 (Native) Parent Process:        bash [8987] Responsible:           Terminal [299] User ID:               501  Date/Time:             2016-09-11 01:05:25.158 +0500 OS Version:            Mac OS X 10.11.6 (15G31) Report Version:        11 Anonymous UUID:        4063B9C3-F525-D9BD-EF5E-358810571673  Sleep/Wake UUID:       CA5341A7-C252-4C76-B694-7F2DAE196F79  Time Awake Since Boot: 57000 seconds Time Since Wake:       1600 seconds  System Integrity Protection: enabled  Crashed Thread:        0  Dispatch queue: com.apple.main-thread  Exception Type:        EXC_BAD_ACCESS (SIGSEGV) Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000068  VM Regions Near 0x68: -->      __TEXT                 0000000100c4e000-0000000100c6a000 [  112K] r-x/rwx SM=COW  /Users/USER/Library/Developer/Xcode/DerivedData/Theisis-gszeehddtmnlkqdbicpeffygvkcw/Build/Products/Release/Theisis   Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0   libsystem_c.dylib               0x00007fff93a8b09e flockfile + 4 1   libsystem_c.dylib               0x00007fff93a8d463 fscanf + 156 2   Theisis                         0x0000000100c57853 app_initialize + 195 (app.m:614) 3   Theisis                         0x0000000100c4f245 main + 453 (main.m:205) 4   libdyld.dylib                   0x00007fff8e0575ad start + 1  Thread 0 crashed with X86 Thread State (64-bit):    rax: 0x00007fff5efb1970  rbx: 0x0000000000000000  rcx: 0x00000b0000000000  rdx: 0x0000000100c6aa8c   rdi: 0x0000000000000000  rsi: 0x0000000100c675d4  rbp: 0x00007fff5efb1860  rsp: 0x00007fff5efb1860    r8: 0x00000000fffffffc   r9: 0x00007fff740b1c10  r10: 0x00007fff97709e01  r11: 0x00007fff93a8d3c7   r12: 0x450022575a4d98d4  r13: 0x0000000000000000  r14: 0x0000000100c675d4  r15: 0x0000000000000000   rip: 0x00007fff93a8b09e  rfl: 0x0000000000010246  cr2: 0x0000000000000068  Logical CPU:     4 Error Code:      0x00000004 Trap Number:     14  VM Region Summary: ReadOnly portion of Libraries: Total=176.1M resident=0K(0%) swapped_out_or_unallocated=176.1M(100%) Writable regions: Total=19.6M written=0K(0%) resident=0K(0%) swapped_out=0K(0%) unallocated=19.6M(100%)                                  VIRTUAL   REGION  REGION TYPE                        SIZE    COUNT (non-coalesced)  ===========                     =======  =======  Activity Tracing                  2048K        2  Kernel Alloc Once                    4K        2  MALLOC                            9604K       17  Stack                             64.0M        3  VM_ALLOCATE                          4K        2  __DATA                            8300K      141  __LINKEDIT                        91.4M        4  __TEXT                            84.7M      146  __UNICODE                          552K        2  shared memory                        8K        3  ===========                     =======  =======  TOTAL                            260.2M      312  

However, when i checked app.m:614 it has if (strcmp(c, "regress_asim") != 0) { where c is a chracter array and this array is working fine from last couple of months and in XCode too. Can anybody tell me what am i missing?

UPDATE:

1) The Resolved Project settings for both Debug and Release are same (except for the binary paths for sure)

2) Code not only works in XCode but is also working in eclipse and creating a working binary.

3) The part of the code that crashes in that the array c is:

Declared as

char c[100]; 

Initillized as

 strncpy(c, "Equation_Default_data.csv", sizeof(c)); 

The code block where it crashes

 if (!startfromcheckpoint) {         oprintf( OUT_PRG, 50, "not starting from checkpoint file.\n");          param = get_parameter("app.fitness_cases");         if (param == NULL)             fitness_cases = 200;         else {             fitness_cases = atoi(param);             if (fitness_cases < 0)                 error( E_FATAL_ERROR,                       "invalid value for \"app.fitness_cases\".");         }         FILE *in_file = fopen(c, "r");         fscanf(in_file, "%d", &fitness_cases);         if (strcmp(c, "regress_asim") != 0) {  //Line 614             app_y_desired = (double *) MALLOC(fitness_cases * sizeof(double));             app_fitness_cases[0] = (double *) MALLOC(                                                      fitness_cases * sizeof(double));             app_fitness_cases[1] = (double *) MALLOC(                                                      fitness_cases * sizeof(double));             app_fitness_cases[2] = (double *) MALLOC(                                                      fitness_cases * sizeof(double));             app_fitness_cases[3] = (double *) MALLOC(                                                      fitness_cases * sizeof(double));              memset(app_fitness_cases[2], 0, fitness_cases * sizeof(double));             memset(app_fitness_cases[3], 0, fitness_cases * sizeof(double));             memset(app_y_desired, 0, fitness_cases * sizeof(double));          }         app_fitness_importance = (int *) MALLOC(fitness_cases * sizeof(int));         //Asim Code         double x, y;         for (i = 0; i < fitness_cases; ++i) {             fscanf(in_file, "%lf", &x);             fscanf(in_file, "%lf", &y);             app_fitness_cases[0][i] = x;             app_fitness_cases[1][i] = y;             if (strcmp(c, "regress_asim") != 0) {                 app_y_desired[i] = y;             }             app_fitness_importance[i] = checkImportance(x);         }         fclose(in_file);         datapointsPerImportance = (int*) MALLOC((max_datapoint_importance+1)*sizeof(int));         memset(datapointsPerImportance, 0, (max_datapoint_importance+1)*sizeof(int));         for (i = 0; i < fitness_cases; ++i) {           // printf("%d : %d\n",i,checkImportance(app_fitness_cases[0][i]));             datapointsPerImportance[checkImportance(app_fitness_cases[0][i])]=datapointsPerImportance[checkImportance(app_fitness_cases[0][i])]+1;          }         for(int i=0;i<=max_datapoint_importance;i++)         {             printf("Importance %d =%d\n",i,datapointsPerImportance[i]);         }         /*oprintf( OUT_PRG, 50, "%d fitness cases:\n", fitness_cases);          for (i = 0; i < fitness_cases; ++i) {          x = (random_double() * 2.0) - 1.0;           // change this line to modify the goal function.          y = x * x * x * x + x * x * x + x * x + x;           app_fitness_cases[0][i] = x;          app_fitness_cases[1][i] = y;           // oprintf( OUT_PRG, 50, "    x = %12.5lf, y = %12.5lf\n", x, y);          }*/     } else {         oprintf( OUT_PRG, 50, "started from checkpoint file.\n");     } 

3 Answers

Answers 1

Without seeing the code, this is like repairing a car in absolute darkness. Try it.

However, I'll give it a try.

In the stack dump, it shows that you are using fscanf to read data from a file. Later, strcmp crashes.

The obvious idea is that fscanf reads more characters than can fit in the char array, which leaves no space for the closing \0. strcmp (or any other code, doesn't really matter) the runs past the end of the string, until it hits something sensible, and then it crashes.

If this is the reason, making the buffer longer would fix it (temporarily). Set it something huge, like 4096, to verify the approach, and then find the real fix.

If you ask why the same program would work in one place, but not in the other - you are probably reading a different file, so the content of the file has different lengths; or you simple reading the file in a different directory, which has a longer name; any of those can be the reason for the char array overflow.

Second idea: The dump line VM Regions Near 0x68 shows the memory area where it dumped, and its content looks like a part of a ls result or a path/filename (/Users/USER/Library/Developer/Xcode/DerivedData/Theisis-gsze....), so potentially your variable for that path is too short. Make that one longer too and try.

Edit: c[100] is too small, the path shown there is 115 chars. Note that .\Thesis will be replaced by \Users\... by the OS, which then is longer than 100 chars.
Declare c[260] (or even larger) and you will be good.

Answers 2

According to these lines in the debug output:

 Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0   libsystem_c.dylib               0x00007fff93a8b09e flockfile + 4 1   libsystem_c.dylib               0x00007fff93a8d463 fscanf + 156 

What is causing the crash is the fscanf, not the strcmp. Check the return values from fopen, it must be NULL in your test case (most probably the file that is being read hasnt been found; when running the program from XCode, the working directory may not be the same as you were expecting).

In your case, this should suffice:

FILE *in_file = fopen(c, "r"); if (in_file == NULL) {     perror( "The following IO error occurred" );     error( E_FATAL_ERROR, "IO error" ); } int r = fscanf(in_file, "%d", &fitness_cases); if (r != 1) {     perror( "The following IO error occurred" );     error( E_FATAL_ERROR, "Read Error" ); } 

Assuming that your error function jumps out of the function. If not, use some returns;

Answers 3

You need to check return values in C

    FILE *in_file = fopen(c, "r");     /* insert error checking code here */     fscanf(in_file, "%d", &fitness_cases);     /* otherwise it fails here when fscanf tries to read from NULL */     if (strcmp(c, "regress_asim") != 0) {  //Line 614 

From the looks at the rest of the posted code, it looks like error checking is an issue (MALLOC?) so the copying of the file path (not posted?) probably has the same issues and overflows the "c" buffer, causing fopen to return NULL and causing fscanf to fail. CHECK RETURN VALUES... if strncpy returns a string that doesn't have '\0' in c[sizeof(c)-1] - you cannot use it to open a file.

Read More