开发者

capture a call stack and have it execute in a different thread

开发者 https://www.devze.com 2023-01-07 14:47 出处:网络
I need to write a logging api which does the actual logging on a seperate thread. i.e. I have an application which wants to log some information. It calls my API and the api captures all the argument

I need to write a logging api which does the actual logging on a seperate thread.

i.e. I have an application which wants to log some information. It calls my API and the api captures all the arguments etc and then hands that off to a seperate thread to be logged.

The logger api accepts variadic arguments and therefore my initial thoughts were to capture the whole call stack and somehow hand it to the thread whcih will do the logging.

I'm reasonable happy that I can capture the call stack. However I'm not sure how I'd pass this call stack off to another method.

I'm using g++ on linux and it may also have to work with Sun's CC v12 on solaris.开发者_JAVA技巧

Any ideas.


You could capture a fixed amount of bytes on the call stack, but you have to copy all that memory even when it's not necessary and put it on a queue of some sort to pass it to the logging thread. Seems like a lot of work to get working, and quite inefficient.

I assume you're using a separate logging thread to make the logging API more efficient. It's quite probable that it's more efficient in this case to have the logging API extract the variadic parameters, convert them into a simpler representation (for example the string to be logged) and queue that.

Note also that a good logging API shouldn't block, so I'd advise a lock-free queue between the logging API and the logging thread.


Is the problem that you don't know how to hand it off to another thread, the simplest thing is to have a queue (std::deque, probably) of callstacks with a mutex protecting it. When your application has generated a callstack, it would then lock the mutex, push the callstack on, amd unlock the mutex. The logging thread periodically locks the mutex, checks the size of the queue, and if it's not empty, takes a callstack off and processes it.

There are ways to improve the efficiency there (eg. condition variables, using a separate counter so you don't have to lock before checking the size, or even using non-locking data structures) but I would recommend not worrying about those until they show up in profiling.


Alternative approach can be:

  1. Define a macro which prints the function name and some additional information like file name, line number etc using standard predefined macros. You can even pass some additional log information which you would otherwise use printf for. This will call the function to send data to your other thread. That thread can wait on a socket/pipe. Write data into that and you can then read from it using the system calls (write/read/pipe).
  2. Now insert this macro at the start of every function/API. You can get the callflow(call stack)
  3. Your logging thread can then use the information from this macro to write to file, display on the console etc.

    define PRINT_LOG(X) function_to_pass_data_to_thread(X,FILE,LINE);

        API1()
    {
       PRINT_LOG("Entered API1");
       //Your API here
    

    }

PS: Sorry about shoddy editing. I cant seem to understand whats the problem today with the editor. Need to log a SO bug i guess.;)

0

精彩评论

暂无评论...
验证码 换一张
取 消