How to debug Linux dom0 kernel in Xen - remote-debugging

I have been hacking on the Xen block driver backend and have been having some difficulty debugging using kgdb over serial. Here is my setup. I'm running MacOS X as host OS. I have two VirtualBox VMs, call them dev and test. VirtualBox is configured to give each of them a COM1 port connected to a named host pipe. I then use socat -d -d ./test-com1 ./dev-com1 to connect the two ports. I have verified after doing this that I can send text plain text from one VM to the other either by doing echo hi > /dev/[ttyS0|hvc0] or using socat. I can also get console output coming out of test during bootup by using socat on dev.
Here's my grub entry for the test kernel:
menuentry 'Debian GNU/Linux, with Linux 3.3.6-xen-ljx-g6304e82 and XEN 4.1.2' --class debian --class gnu-linux --class gnu --class os --class xen {
insmod part_msdos
insmod ext2
set root='(hd0,msdos1)'
search --no-floppy --fs-uuid --set 0c98efb4-f40e-4f0e-a2d3-2ed39b0a5070
echo 'Loading Linux 3.3.6-xen-ljx-g6304e82 ...'
multiboot /boot/xen-4.1.2.gz placeholder loglvl=all guest_loglvl=all com1=115200,8n1,0x3f8,4 console=com1,vga
module /boot/vmlinuz-3.3.6-xen-ljx-g6304e82 placeholder root=UUID=0c98efb4-f40e-4f0e-a2d3-2ed39b0a5070 ro console=hvc0 console=tty0 earlyprintk=xen nopat quiet
echo 'Loading initial ramdisk ...'
module /boot/initrd.img-3.3.6-xen-ljx-g6304e82
}
This is from dev:
user#jimmy:~/workspace/linux-3.3.6$ stty -F /dev/ttyS0 -a
speed 38400 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 0; time = 10;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl -echoke
This is from test:
root#sqtest:~# stty -F /dev/tty0 -a
speed 38400 baud; rows 25; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
ignbrk -brkint ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl -ixon -ixoff -iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
-isig -icanon -iexten -echo -echoe -echok -echonl -noflsh -xcase -tostop -echoprt -echoctl -echoke
root#sqtest:~# stty -F /dev/hvc0 -a
speed 38400 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
An example dev session (after doing echo hvc0,38400 > /sys/module/kgdboc/parameters/kgdboc; echo g > /proc/sysrq-trigger on test):
user#jimmy:~/workspace/linux-3.3.6$ gdb vmlinux
GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/paton/workspace/linux-3.3.6/vmlinux...done.
(gdb) set remotebaud 38400
(gdb) target remote /dev/ttyS0
Remote debugging using /dev/ttyS0
Ignoring packet error, continuing...
warning: unrecognized item "timeout" in "qSupported" response
Ignoring packet error, continuing...
Same thing happens when I use tty0 instead of hvc0 above.
I have been able to successfully connect the debugger when using my kernel without Xen, although the serial TTY settings are different. I have a feeling it has something to do with the options as reported by STTY, but I'm hoping someone who knows more about those things can point out the problem so I understand.
Thank you!

Turns out you can't do it. However, there is a Linux patch located here:
http://lists.xen.org/archives/html/xen-devel/2012-06/msg00326.html
That's for 3.2 kernel. I posted one for 3.3 in that same thread. This patch enables kgdb debugging over hvc.

Related

Get stracktrace on application built with G++ on Windows

I'm developping an application on Windows using G++/MinGW. When my application crash, I would like to log the stacktrace. I understand that I cannot use "SymGetSymFromAddr" function to retrieve the method name because it works only on executable built with Visual Studio (PDB format).
Therefore, my idea is to print only the debug symbol addresses and then use "addr2line" tool to retrieve the method name / line number.
Here is the code to print the stacktrace method name addresses:
LONG WINAPI signalHandler(EXCEPTION_POINTERS* exceptionInfo) {
HANDLE process = GetCurrentProcess();
HANDLE thread = GetCurrentThread();
CONTEXT* context = exceptionInfo->ContextRecord;
SymInitialize(process, nullptr, true);
STACKFRAME frame = {};
frame.AddrPC.Offset = context->Rip;
frame.AddrPC.Mode = AddrModeFlat;
frame.AddrStack.Offset = context->Rsp;
frame.AddrStack.Mode = AddrModeFlat;
frame.AddrFrame.Offset = context->Rbp;
frame.AddrFrame.Mode = AddrModeFlat;
std::stringstream ss;
while (StackWalk(IMAGE_FILE_MACHINE_AMD64, process, thread, &frame, context, nullptr, SymFunctionTableAccess, SymGetModuleBase, nullptr)) {
std::string moduleName = "[unknown]";
DWORD64 moduleBase = SymGetModuleBase(process, frame.AddrPC.Offset);
char moduleBuffer[MAX_PATH];
if (moduleBase && GetModuleFileNameA((HINSTANCE)moduleBase, moduleBuffer, MAX_PATH)) {
moduleName = moduleBuffer;
}
void* instructionShift = (char*)frame.AddrPC.Offset;
ss << "\t[bt]\t> " << "addr2line -f -e " << moduleName << " " << instructionShift << std::endl;
}
SymCleanup(process);
Logger::instance().logError(ss.str());
return EXCEPTION_EXECUTE_HANDLER;
}
Here is an example of result when I've got an application crash:
[bt] > addr2line -f -e C:\msys64\home\greg\project\myApp.exe 0x7ff611d13faf
[bt] > addr2line -f -e C:\msys64\home\greg\project\myApp.exe 0x7ff611d13763
[bt] > addr2line -f -e C:\msys64\home\greg\project\myApp.exe 0x7ff611daf325
[bt] > addr2line -f -e C:\WINDOWS\System32\USER32.dll 0x7ffde66f1c4c
[bt] > addr2line -f -e C:\WINDOWS\System32\USER32.dll 0x7ffde66f189e
[bt] > addr2line -f -e C:\WINDOWS\SYSTEM32\opengl32.dll 0x7ffd864e3554
[bt] > addr2line -f -e C:\WINDOWS\System32\USER32.dll 0x7ffde66f1c4c
[bt] > addr2line -f -e C:\WINDOWS\System32\USER32.dll 0x7ffde66f0ea6
[bt] > addr2line -f -e C:\msys64\home\greg\project\myApp.exe 0x7ff611db218f
[bt] > addr2line -f -e C:\msys64\home\greg\project\myApp.exe 0x7ff611d13a8f
[bt] > addr2line -f -e C:\msys64\home\greg\project\myApp.exe 0x7ff611d114c6
[bt] > addr2line -f -e C:\WINDOWS\System32\KERNEL32.DLL 0x7ffde57b54e0
[bt] > addr2line -f -e C:\WINDOWS\SYSTEM32\ntdll.dll 0x7ffde788485b
Unfortunately, when I execute the "addr2line" command, I always get the following result:
??
??:0
I well compiled my application with debug option (-g). Therefore, why the method name is not returned by "addr2line" tool ? Or maybe it is not possible to get correct addresses with "StackWalk" function on application built with G++ ?

Why is advertising with ADV_DATA producing Invalid Parameters

I'm trying to write some BlueZ code using the Management API but I can't seem to get BlueZ to advertise arbitrary data on the advertisement system
I have 2 tests one in C++ and one using the btmgmt tool that BlueZ has released
When I run this command it fails this way
btmgmt add-adv -d 8C33 1
Add Advertising failed with status 0x0d (Invalid Parameters)
The equivalent C++ code also fails identically
#include <iostream>
extern "C" {
#include "external/bluetooth/lib/bluetooth.h"
#include "external/bluetooth/lib/mgmt.h"
#include "external/bluetooth/lib/hci.h"
#include "external/bluetooth/lib/hci_lib.h"
#include "external/bluetooth/src/shared/mgmt.h"
}
static void setup_dv(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
std::cout << "good" << std::endl;
}
struct CPadvertising {
uint8_t instance;
uint32_t flags;
uint16_t duration;
uint16_t timeout;
uint8_t adv_data_len;
uint8_t scan_rsp_len;
uint8_t data[4];
} __packed;
int main()
{
mgmt* sock = mgmt_new_default();
CPadvertising* data = new CPadvertising();
data->instance = 1;
data->duration = 2;
data->timeout = 100;
data->adv_data_len = 4;
data->scan_rsp_len = 0;
data->flags = 0;
data->data[0] = 8;
data->data[1] = 12;
data->data[2] = 3;
data->data[3] = 3;
mgmt_send(sock, MGMT_OP_ADD_ADVERTISING, index,
sizeof(CPadvertising), data, setup_dv, nullptr, nullptr);
auto loop = g_main_loop_new(nullptr, FALSE);
g_main_loop_run(loop);
}
has this output in btmon
# MGMT Command: Add Advertising (0x003e) plen 13 {0x0003} [hci0] 98.205359
Instance: 1
Flags: 0x00000000
Duration: 2
Timeout: 100
Advertising data length: 4
8 c 3 3 .3
Scan response length: 0
# MGMT Event: Command Status (0x0002) plen 3 {0x0003} [hci0] 98.205376
Add Advertising (0x003e)
Status: Invalid Parameters (0x0d)
Referring to these docs, I should not get invalid parameter for any of this but I do
https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/mgmt-api.txt
However, I know certain types of data does indeed work
btmgmt add-adv -d 080954657374204C45
works even in an even weirder way prompting this output on btmon
# MGMT Command: Add Advertising (0x003e) plen 20 {0x0002} [hci0] 143.671485
Instance: 1
Flags: 0x00000000
Duration: 0
Timeout: 0
Advertising data length: 9
Name (complete): Test LL <--- What is this
Scan response length: 0
Looking at the source for btmgmt, these are the options available:
static void add_adv_usage(void)
{
bt_shell_usage();
print("Options:\n"
"\t -u, --uuid <uuid> Service UUID\n"
"\t -d, --adv-data <data> Advertising Data bytes\n"
"\t -s, --scan-rsp <data> Scan Response Data bytes\n"
"\t -t, --timeout <timeout> Timeout in seconds\n"
"\t -D, --duration <duration> Duration in seconds\n"
"\t -P, --phy <phy> Phy type, Specify 1M/2M/CODED\n"
"\t -c, --connectable \"connectable\" flag\n"
"\t -g, --general-discov \"general-discoverable\" flag\n"
"\t -l, --limited-discov \"limited-discoverable\" flag\n"
"\t -n, --scan-rsp-local-name \"local-name\" flag\n"
"\t -a, --scan-rsp-appearance \"appearance\" flag\n"
"\t -m, --managed-flags \"managed-flags\" flag\n"
"\t -p, --tx-power \"tx-power\" flag\n"
"e.g.:\n"
"\tadd-adv -u 180d -u 180f -d 080954657374204C45 1");
}
Looking at the advert that worked, the first number is the length of the data, the second is the data_type, and the rest is the local name string. So:
0x08 = Length of datatype is 8
0x09 = Data type is <Complete Local Name>
0x54 = T
0x65 = e
0x73 = s
0x74 = t
0x20 = ' '
0x4C = L
0x45 = E
Not sure why that has turned up as Test LL in the btmon output. I'll
assume it was a slightly different run that you recorded.
Looking at your data of 8c33; the 8c does not represent the length and 33 is not a valid data type.
I suspect what you want to do is send manufacturer data. Assuming you don't have a company identifier, then you can use 0xffff for testing purposes.
This would be a command of:
btmgmt add-adv -d 05ffffff8C33 -g 1
Which gave the following in btmon
# MGMT Command: Add Adver.. (0x003e) plen 17 {0x0002} [hci0] 341.378134
Instance: 1
Flags: 0x00000002
Advertise as Discoverable
Duration: 0
Timeout: 0
Advertising data length: 6
Company: internal use (65535)
Data: 8c33
Scan response length: 0

QProcess on MacOS trying to use diskutil

Qt 5.12
I am trying to get the volume ID on macOS and using the following function:
QString getVolumeInfo()
{
QString volumeID = "Cannot find the volumeID";
QProcess p;
//diskutil info $(df -h / | tail -1 | cut -d' ' -f 1)
QString command = "diskutil";
QStringList args;
args << "info" << "$(df -h / | tail -1 | cut -d' ' -f 1)";
p.start(command, args);
p.waitForStarted();
p.waitForFinished();
foreach(QString line, QString(p.readAll()).split("\n"))
{
if(line.contains("Volume UUID:"))
volumeID = line;
}
return volumeID;
}
I have to use the diskutil because of the limitation with macOS. However, QProcess, reading the object has nothing in it.
Command on terminal: diskutil info $(df -h / | tail -1 | cut -d' ' -f 1)
which returns a ton of information like:
...
SMART Status: Verified
Volume UUID: 954BACF1-EBC5-4D14-86FB-0912CF7F839C
Disk / Partition UUID: 954BACF1-EBC5-4D14-86FB-0912CF7F839C
Disk Size: 500.1 GB (500068036608 Bytes) (exactly 976695384 512-Byte-Units)
....
When I try to add qDebug() to debug I get the following: true - "Could not find disk: $(df -h / | tail -1 | cut -d' ' -f 1)\n"
So seem like the arguments is not formatted or something?
I am trying to implement: https://apple.stackexchange.com/questions/50302/how-can-i-tell-which-volume-the-operating-system-is-on
The slight modification after Eelke explained.
QStringList args;
args << "-c" << "diskutil info $(df -h / | tail -1 | cut -d' ' -f 1)";
p.start("/bin/bash", args);

Calling FFMPEG with Boost.Process

I'm trying to call FFMPEG from my C++ process to stream video from an IP camera. The FFMPEG command I use is ffmpeg.exe -rtsp_transport tcp -i rtsp://10.0.1.21/ONVIF/MediaInput?profile=1_def_profile4 -f image2pipe -pix_fmt rgb24 -vcodec rawvideo -r 15 -. I've verified this command in the command prompt and it does start a video stream and dumps the frames to stdout. I've also written similar code in Python and it works.
This is the code I'm using to call FFMPEG with the arguments from the previous paragraph in C++ and read the individual frames from stdout.
bool build_ffmpeg_arguments(const std::string &uri, std::vector<std::string> &args)
{
args.push_back("-rtsp_transport");
args.push_back("tcp");
args.push_back("-i");
args.push_back(uri);
args.push_back("-f");
args.push_back("image2pipe");
args.push_back("-pix_fmt");
args.push_back("rgb24");
args.push_back("-vcodec");
args.push_back("rawvideo");
args.push_back("-r");
args.push_back("15");
args.push_back("-");
return true;
}
boost::process::child start_ffmpeg(const std::string &uri,
const std::string &ffmpeg_path = "c:\\Tools\\ffmpeg.exe")
{
std::vector<std::string> args;
build_ffmpeg_arguments(uri, args);
boost::process::context ctx;
ctx.stdout_behavior = boost::process::capture_stream();
ctx.stderr_behavior = boost::process::capture_stream();
return boost::process::launch(ffmpeg_path, args, ctx);
}
bool read_frame(boost::process::pistream &is, int frame_size, std::vector<char> &frame_bytes)
{
char *buffer = new char[frame_size];
frame_bytes.clear();
is.read(buffer, frame_size);
int bytes_read = is.gcount();
frame_bytes.assign(buffer, buffer + bytes_read);
// std::cout << "Is Bad: " << is.bad() << std::endl;
// std::cout << "Is EOF: " << is.eof() << std::endl;
// std::cout << "gcount: " << bytes_read << std::endl;
delete[] buffer;
if(is.bad() || is.eof() || bytes_read < frame_size)
{
//We read in gunk, skip this time.
is.clear();
return false;
}
else
{
return true;
}
}
//This is where the code is invoked.
BOOST_AUTO_TEST_CASE(test_ffmpeg_stream)
{
std::string uri = "rtsp://10.0.1.21/ONVIF/MediaInput?profile=1_def_profile4";
int width = 320;
int height = 240;
int bpp = 3;
int bytes_expected = width * height * 3;
boost::process::child c = start_ffmpeg(uri);
boost::process::pistream &is = c.get_stdout();
boost::process::pistream &err = c.get_stderr();
std::vector<char> buffer;
bool result = read_frame(is, bytes_expected, buffer);
//BOOST_CHECK_EQUAL(true, result);
std::cout << "Buffer size: " << buffer.size() << std::endl;
std::string line;
while (std::getline(err, line))
std::cout << line << std::endl;
}
The output from stderr suggests that the parameters could be passed in wrong.
ffmpeg version 2.8.3 Copyright (c) 2000-2015 the FFmpeg developers
built with gcc 5.2.0 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-av
isynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enab
le-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --
enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-l
ibilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enab
le-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --en
able-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --ena
ble-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc
--enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enabl
e-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma --ena
ble-decklink --enable-zlib
libavutil 54. 31.100 / 54. 31.100
libavcodec 56. 60.100 / 56. 60.100
libavformat 56. 40.101 / 56. 40.101
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 40.101 / 5. 40.101
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 2.101 / 1. 2.101
libpostproc 53. 3.100 / 53. 3.100
rtsp://10.0.1.21/ONVIF/MediaInput?profile=1_def_profile4: Unknown error
Is there a way of showing the full command line with arguments that boost::process::launch is calling? Is there anything obvious that I'm doing wrong with boost::process?
Update:
Suspecting that it could be the command line arguments being passed in wrong, I've created a dummy executable that prints out the command line arguments it receives. It's a drop-in replacement for ffmpeg.exe purely so that I can see what command lines are being passed. The command line I'm getting is -rtsp_transport tcp -i rtsp://10.0.1.21/ONVIF/MediaInput?profile=1_def_profile4 -f image2pipe -pix_fmt rgb24 -vcodec rawvideo -r 15 -. Manually calling ffmpeg with that command line works as expected. Yet somehow it doesn't work when launched via boost::process.
** Solution **
It looks like I need to set the the environment field of the context. No idea why that fixes the problem, but it does.
boost::process::context ctx;
ctx.environment = boost::process::self::get_environment();
ctx.stdout_behavior = boost::process::capture_stream();
ctx.stderr_behavior = boost::process::capture_stream();

Use Named Pipe (C++) to send images to FFMPEG

I have the following code in C++:
#include <iostream>
#include <windows.h>
#include <iostream> // std::cout
#include <fstream> // std::ifstream
#include <vector>
#include <stdlib.h>
using namespace std;
int main(int argc, const char **argv)
{
wcout << "Creating an instance of a named pipe..." << endl;
// Create a pipe to send data
HANDLE pipe = CreateNamedPipe(
L"\\\\.\\pipe\\my_pipe", // name of the pipe
PIPE_ACCESS_OUTBOUND, // 1-way pipe -- send only
PIPE_TYPE_BYTE, // send data as a byte stream
1, // only allow 1 instance of this pipe
0, // no outbound buffer
0, // no inbound buffer
0, // use default wait time
NULL // use default security attributes
);
if (pipe == NULL || pipe == INVALID_HANDLE_VALUE) {
wcout << "Failed to create outbound pipe instance.";
// look up error code here using GetLastError()
system("pause");
return 1;
}
wcout << "Waiting for a client to connect to the pipe..." << endl;
// This call blocks until a client process connects to the pipe
BOOL result = ConnectNamedPipe(pipe, NULL);
if (!result) {
wcout << "Failed to make connection on named pipe." << endl;
// look up error code here using GetLastError()
CloseHandle(pipe); // close the pipe
system("pause");
return 1;
}
wcout << "Sending data to pipe..." << endl;
//opening file
ifstream infile;
infile.open("E:/xmen.jpg",std::ios::binary);
ofstream out("E:/lelel.jpg",std::ios::binary);
infile.seekg(0,std::ios::end);
size_t file_size_in_byte = infile.tellg();
vector<char> file_vec;
file_vec.resize(file_size_in_byte);
infile.seekg(0,std::ios::beg);
infile.read(&file_vec[0],file_size_in_byte);
out.write(&file_vec[0],file_vec.size());
wcout<<file_size_in_byte<<endl;
// This call blocks until a client process reads all the data
DWORD numBytesWritten = 0;
result = WriteFile(
pipe, // handle to our outbound pipe
&file_vec[0], // data to send
61026, // length of data to send (bytes)
&numBytesWritten, // will store actual amount of data sent
NULL // not using overlapped IO
);
if (result) {
wcout << "Number of bytes sent: " << numBytesWritten << endl;
} else {
wcout << "Failed to send data." << endl;
// look up error code here using GetLastError()
}
// Close the pipe (automatically disconnects client too)
CloseHandle(pipe);
wcout << "Done." << endl;
system("pause");
return 0;
}
Which I use to create a named pipe \\.\pipe\my_pipe, to which FFMPEG connects to, using the following command:
64-static\bin\Video>ffmpeg.exe -loop 1 -s 4cif -f image2 -y -i \\.\pipe\\my_pipe
-r 25 -vframes 250 -vcodec rawvideo -an eaeew.mov
Output:
ffmpeg version N-54233-g86190af Copyright (c) 2000-2013 the FFmpeg developers
built on Jun 27 2013 16:49:12 with gcc 4.7.3 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib libavutil 52. 37.101 / 52. 37.101
libavcodec 55. 17.100 / 55. 17.100
libavformat 55. 10.100 / 55. 10.100
libavdevice 55. 2.100 / 55. 2.100
libavfilter 3. 77.101 / 3. 77.101
libswscale 2. 3.100 / 2. 3.100
libswresample 0. 17.102 / 0. 17.102
libpostproc 52. 3.100 / 52. 3.100
[image2 # 0000000003ee04a0] Could find no file with with path '\\.\pipe\\my_pipe
' and index in the range 0-4
\\.\pipe\\my_pipe: No such file or directory
I can see on my console that my C++ app received a connection, but I get the error above in FFMPEG. Can someone please advise?
EDIT 1
Using the command below
ffmpeg.exe -s 4cif -i \\.\pipe\my_pipe -r 25 -vframes 250 -vcodec rawvideo -an tess.mov
I get the following output
ffmpeg version N-54233-g86190af Copyright (c) 2000-2013 the FFmpeg developers
built on Jun 27 2013 16:49:12 with gcc 4.7.3 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
libavutil 52. 37.101 / 52. 37.101
libavcodec 55. 17.100 / 55. 17.100
libavformat 55. 10.100 / 55. 10.100
libavdevice 55. 2.100 / 55. 2.100
libavfilter 3. 77.101 / 3. 77.101
libswscale 2. 3.100 / 2. 3.100
libswresample 0. 17.102 / 0. 17.102
libpostproc 52. 3.100 / 52. 3.100
\\.\pipe\my_pipe: Invalid data found when processing input
So, now it seems it was able to connect to the pipe but is not able to process the input.
I'm doing the same thing but with normal pipe, not named one. My code is working great. Hope it helps
#include <stdio.h>
#include <iostream>
#include <iomanip>
using namespace std;
int main(int argc, char **argv) {
FILE *pPipe;
long lSize;
char * imgdata;
int imgcols = 640, imgrows = 480, elemSize = 3;
imgdata = ...;
stringstream sstm;
sstm << "/usr/local/bin/ffmpeg -y -f rawvideo -vcodec rawvideo -s " << imgcols << "x" << imgrows <<" -pix_fmt rgb24 -i - -c:v libx264 -shortest my_output.mp4";
if ( !(pPipe = popen(sstm.str().c_str(), "w")) ) {
cout << "popen error" << endl;
exit(1);
}
// open a pipe to FFmpeg
lSize = imgrows * imgcols * elemSize;
// write to pipe
fwrite(imgdata, 1, lSize, pPipe);
fflush(pPipe);
fclose(pPipe);
return 0;
}