mercredi 6 décembre 2017

Trigger a Breakpoint and attach a debugger (Just-In-time Debugger)

Debugging program made to procress stdin data to stdout may be a mess, because piping data while running the debugger from Visual Studio is not easy.

A well known trick was to insert an interruption 3 into the code to trigger a break, see My favorite interruption

__asm int 3;

But as inline assembly is not supported by the x64 visual studio compiler, you may consider using the _debugbreak() function instead.

https://msdn.microsoft.com/fr-fr/library/f408b4et.aspx

#include
....

main() {  
   __debugbreak();  
}  

But I was facing an interesting  issue where that instruction was finally just terminate the program, instead of triggering a message box like the following



I found that there is several registry key which can be use to configure what we want to do in case of crash, break, etc...


  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug 
  • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
By default, in the AeDebug key, you should find a value "Debugger" set to "C:\WINDOWS\system32\vsjitdebugger.exe" -p %ld -e %ld.

So if you see that a break isnot trigger or catch by the Just-in-Time Debugger, just add another value called Auto, of type REG_SZ  and set its value to 1.

Regards, 


mercredi 11 mai 2016

Do it at compile time !


I found that picture this morning in the CodeProject daily mail and I was thinking about the answer I will give ! And for me the best is let the compiler work as much as possible.... so :







vendredi 17 avril 2015

Bash script: extract info from ffmpeg output.

Hi,
I already script that a several time and I think it's will be a good time to take a note and save a bit my mind for the next time !

When we use ffmpeg in some complex script in which we pipe decoded frame into another process i.e an encoder, it's really useful to get all input video and audio info. But from the ffmpeg -i output there is several regular expression that you can use:

  • Extract widthxheigth:
RESINFO=`$FFMPEGCMD -i $INPUTFILE 2>&1 | grep Stream | grep -oP ', \K[0-9]+x[0-9]+'`






  •  Extract frame-rate:
FPS=`$FFMPEGCMD -i $INPUTFILE 2>&1 | grep Stream | sed -n "s/.*, \(.*\) tb.*/\1/p"`





  • Split RESINFO into Width and Heigth
WIDTH=`echo $RESINFO | grep -oP '^\K[0-9]+'`
HEIGHT=`echo $RESINFO | grep -oP '\K[0-9]+$'`

Feel free to comment and add request/proposal if you think that there is a better/other way to do it !

mercredi 25 mars 2015

My favorite 'interruption' ...

Today, I made by mistake an interesting commit ! In fact, I'm working on a simple command line program and that program is design to process data read from the standard input and for my own convenience I added at the beginning of the main a piece of code that some of my teammate didn't know! So let me introduce to you the well known 'interruption 3'.....

#if defined(WIN32) || defined(WIN64)
  __asm int 3;
#endif


int is the asm instruction you use to generate a software interruption. Under windows the interruption 3 execution will trigger a breakpoint and from the outside you will have the usual popup saying:


click "debug" and select debugger you want use :)

It's a trick I often use when I want to also stop at start-up  or at a fixed code point during a dev phase.

mercredi 25 février 2015

Some 'tricks' about ::ftruncate (for windows & linux)

Hi, as today was an interesting development day, where I (with a good advice of one of my teammate) resolved a weird issue, I think it's the good time to write something on that topic because even after some 'Googling' I didn't find anything.

Let's simplify the context.

We just want to open a file, write some text and close it. Later that file will be open again, we will read the text already present and run some text manipulation and rewrite the file.

As the file size and the amount of data we used were small, we use a real simple implementation that we can summarize with the following code.


#include
#include
#include

#include
#include
using namespace std;

int main() {
int fd = -1;
fd = ::open("sample.txt", O_CREAT | O_RDWR, S_IRWXG | S_IRWXO | S_IRWXU);
char* txt = "a small text to fill the file";
::write(fd, txt, strlen(txt));
::close(fd);

fd = ::open("sample.txt", O_CREAT | O_RDWR , S_IRWXG | S_IRWXO | S_IRWXU);
struct stat data;
bool ret = 0 == ::fstat(fd, &data);
if(ret && data.st_size>0)
{
  char* buf = new char[data.st_size+1]; 

  size_t bytesRead = ::read(fd, &buf[0], data.st_size); 
  delete [] buf; 
}
::ftruncate(fd, 0); 
char* txt2 = "another small text to fill the file"; *
::write(fd, txt2, strlen(txt2));
::close(fd); 
 return 0;

Note the call to 'ftruncate' function, we use it to remove the file content. I know that in a real simple code I could have done that in a several others ways (i.e. ::open with O_TRUNC) but consider the fact that our file is shared across multiple process and that the real implementation is a bit more complex.

But let's continue.... The point is that is didn't work as expected. In fact, if the file type was 'ASCII text' after the 1st write, after the second write the file mode changed to 'data' and it wrote the text 'in-binary'. If we don't perform the 'read' or the 'ftruncate' the file type was still the same 'ASCII text'. The solution came from the following: if we 'read' the whole file the reach the end and it may be possible that the file descriptor is in a strange state where it can find the file mode. So we just added a 'seek' before the call to 'ftruncate' and the issues was gone.

i.e. lseek(fd, 0, SEEK_SET);

Easy, but really weird and I didn't find any question and page mentioning that kind of issue ! but there is one :)

That post is related to the question I asked here

vendredi 23 janvier 2015

ffmpeg: all concatenation methods don't lead to a correct file

As I used recently ffmpeg to concatente some really huge video files coming from a CamCorder, I discovered that even if they looks really similar the "Concat protocol" and "Concat demuxer"describe in "Concatenating media files" didn't lead to the same result and that the "Concat demuxer" approach introduced some weird PTS (presentation time stamp) at files boundaries.


As I spend several hour comparing the different way to do that, I can now recommend to use one of those 2 simple methods if you have to concatenate files with the following properties:
  • if they use the same container and codecs
  • if they are consecutive in a way their PTS should not have discontinuities

copy /B 1.MTS+2.MTS out.MTS

or

ffmpeg -i "concat:1.MTS|2.MTS" -an -vcodec copy out.ts
 It should be fast and it should not introduce weird PTS between 1 and 2 !

Observed with:

ffmpeg version N-68482-g92a596f Copyright (c) 2000-2014 the FFmpeg developers
  built on Dec 16 2014 02:53:08 with gcc 4.9.2 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libblu
ray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrw
b --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --
enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-decklink --enable-zlib
  libavutil      54. 15.100 / 54. 15.100
  libavcodec     56. 15.100 / 56. 15.100
  libavformat    56. 15.105 / 56. 15.105
  libavdevice    56.  3.100 / 56.  3.100
  libavfilter     5.  3.101 /  5.  3.101
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  1.100 /  1.  1.100
  libpostproc    53.  3.100 / 53.  3.100

CMAKE script retro-compatibility

Hi,

I didn't post anything for a while, but in since few days, I found several topic for which I would like to write something (It's like a reminder for me ...)

I worked on product that we build on several different linux platform (Centos/Ubuntu/ etc ...). We use cmake and someone updated a script in a way it couldn't work anymore with older version of cmake (prior to 2.8.3). As I implemented a work-around, I wanted to share it because it was an annoying issue.

In cmake v2.8.3, a new "Useful variable" was introduced CMAKE_CURRENT_LIST_DIR.
If you had to use a cmake script in which that variable is used, cmake will not complain, it will just consider the variable as empty.

The work-around use the other function of cmake to initialize that value and let the rest of your script unchanged.

if("${CMAKE_CURRENT_LIST_DIR}" STREQUAL "")
message(STATUS "work-around to get the current folder for cmake version prior to 2.8.3")
get_filename_component(CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
endif()


It's quit simple, first I test if the value is empty, and if it's true I use get_filename_component cmake command to extract the current folder path from the CMAKE_CURRENT_LIST_FILE cmake variable.