LINUX.ORG.RU

Сообщения Cupper

 

Как искать узкие места (bottleneck)

Форум — Development

Какое то неприличное название у темы получилось, ну да ладно.

Хотел бы спросить совета, как вы профилируете свои программы? Как ищите bottleneck'и? В первую очередь интерестно как это делается для сетевых event driven приложений.

valgring + callgrind, очевидно в этом плане не подходит. Так как он замеряет процессорное время. Т.е. он не позволит определить что у вас два потока постоянно тыкаются в один мютекс и ждут его. Helgrind вообще не понятно как применять если в проекте есть что то кроме стандартного мютекса (даже бустовый с его atomic уже наверно вызовет проблеммы).

Google CPU Profiler, уже лучше, хотя я таки тоже не уверен, что он сможет показать, что кто то уткнулся в мютекс. Я спциально попробывал все свои обработчики в приложении стравить на один mutex под которым еще и sleep происходит. Но в результате профилирования, этого участка вообще нету, а большую часть захвал именно IO хотя стреляю все локально.

Я в профилировании еще профан, хотелось бы услышать от кого то более опытного в этом деле на что стоит обратить внимание при профилировании, может быть какие то техники использовать.

Большинство статей которые у нашел/прочитал это самые азы использования профайлера. Так же встречаются статью на счет особенностей ошибочного отображения/подсчета данных профайлером.

Я все больше склоняюсь к тому, что профилирование, это как дезасемблирование. Тут нужны годы снаровки что бы понастоящему извлекать из этого пользу, а не просто тыкаться в непонятные циферки и годать, а гдеж тут жопа зарыта.

 ,

Cupper
()

Не удалять неиспользуемые символы при линковке

Форум — Development

Столкнулся с такой, новой для себя, проблемой. Есть проект построеный по модульной архитектуре. Есть главный бинарник (App), главная динамическая библиотека (A.so) и отдельный модуль (B.so).

Библиотека A.so линкуется с разными сторонними динамическими диблиотеками, типа boost, ssl, crypto. В исходных кодах A.so описываются всякие скущности которые ссылаются на эти сторонние библиотеки.

Основной бинарик App линкуется с A.so и использует только одну маленькую функцию из этой библиотеки. Т.е. не используется ничего связанного с ssl,cryprto, boost и прочим.

Модуль B.so использует сущности связанный с boost,ssl,crypto но не линкует сторонние библиотеки.

Во время сборки всего это получается такая хрень. Так как App не использует явно функции,объекты и прочее определенные в A.so и связанные с boost,ssl,crypto то они тупо отбрасываются линковщиком и их нет ни в зависимостях ни у App ни у A.so.

Далее App через dlopen загружает B.so (который нуждается в boost,ssl,crypto) и, о боже, ни у кого не оказывается этих зависимостей, и я получаю unresolved symbols.

Вопрос, как разрешить эту спорную ситуацию. Проблема усугубляется еще тем что на системе redhat этой проблемы не возникает, и все нужные зависимости оказываются в A.so и также гладко качуют в App, B.so (при ее загрузке). А в ubuntu все не используемые зависимости просто отбрасываются из A.so и из за этого наступает невозможность загрузить B.so который нуждается в этих зависимостях.

Еще раз повторюсь, boost,ssl,crypto используются в исходных кодах динамически загружаемой библиотеки A.so и у нее же в правилах написано линковаться с ними. Но так как это - динамически загружаемая библиотека, то понятно дело они только определяются там, но не используются явно (т.е. не создаются объекты, не вызываются функции). И они отбрасываются и либа не резолвит все используемые в ней сторонние зависимости.

 , ,

Cupper
()

Remote Makefile project with existing Code

Форум — Development

Встала перед мной такая проблема. Нужно вести разработку на удаленной машине. Linux to Linux. Есть существующий проект сборка на основе Cmake. Пытаюсь все эту бойду протащить через Eclipse (kepler).

Пока мало чего полезного получилось. Через RSE(over ssh) подключился в Eclipse. А далее не понимаю как уже развернутый проект импортировать в Eclipse в качестве Remote Makefile project with existing Code.

В идеале хочется добится, что бы исходники лежили удаленно, сборка и отладка производилась удаленно, т.е. что бы Eclipse был как бы порталом на другую машину, при этом абсолютно прозрачно. И вся эта херня еще на git завернута.

Я знаю есть вариант просто на удаленной машине поставить Eclipse и далее подключится к тамашнему Xserver. Но в прошлый раз когда я так делал это сопроваждалась всяческими лагами отображения (ну этож по сути remote desktop). А хотелось бы что бы всетаки Eсlipse был локально и без тормазов.

 

Cupper
()

Исключение в деструкторе

Форум — Development

Какой профит от того, что если в деструкторе было брошено исключение (и оно пока единственное активное), то все равно продолжат вызываться деструкторы суб-классов и базовых классов, но при этом не будет выполнен ::operator delete(void*), т.е. физически память не будет освобождена (по стандарту, да и на практике).

Специально не расписывал пример подробно, так как это либо знаешь либо нет. Я вот например сейчас узнал, но не понял юмора.

 

Cupper
()

Использование bytecode lua 5.2 в С++

Форум — Development

Пытаюсь найти ответ вот на такой вопрос.

Хочу использовать в С++ возможности lua (5.2). Предполагается что будет много скриптов и они должны будут выполять много простой логики. Притом все это дело в разных потоках паралельно и не связано между собой.

Встает вопрос, если использовать простую логику luaL_dofile() то это означает что каждый раз надо считать скприт с диска и переварить его в байткод а только потом выполнить.

Понятно дело хочется чтобы каждый из скриптов был зачитан только единожды и единожды переведен в байт код. А затем Использовать байткод сколько душе угодно.

До версии 5.2 было возможно сделать что то вроде этого

  • luaL_loadfile
  • lua_dump -> to file
  • luaL_loadfile

По крайней мере можно было избавится от промежуточной компиляции. Но оставалось повтороное чтение из файла.

С версии 5.2 luaL_loadfile вообще не умеет загружать байт код. (если я правильно понял они запретили этот функционал).

Возможноли решить поставленную задачу средствами lua? Если нет, то что можно использовать вместо lua?

 ,

Cupper
()

Не загружается GRUB

Форум — Desktop

Доброе утро сообщество.

Помогите решить проблему. Перестал загружаться ноут.

Симптомы: биос загружается, далее после него на черном экране моргает белый курсор. На ввод не откликается, ничего далее не происходит.

Уже пробовал:

  • Проверять на битые блоки и восстанавливать корневой раздел через fsck (об ошибках ничего не написал).
  • Монтировать корневой раздел (монтируется, внешне вроде все на месте).
  • Перезаписывать grub (дважды) (как я понимаю у меня grub2 ибо Ubuntu 12.04).

Все это делал из под соответствующего LiveCD Unubtu 12.04.

Я думал что диск умер, но три верхние пункта говорят об обратном. Подскажите что еще диагностировать можно?

Cupper
()

GTest + CMake

Форум — Development

Пытаюсь к проекту прикрутить тесты. Понял, что абсолютно не понимаю как это сделать и что у меня не так.

Project
	src
		subdirs
		*.cpp
		*.h
	test
		test_*.cpp
	CMakeLists.txt

Корневой CMakeLists.txt выглядит вот так:

set (PROJECT Project)
project (${PROJECT})

set (INCLUDE_DIR ${PROJECT_SOURCE_DIR}/src)
set (SRC_DIR ${PROJECT_SOURCE_DIR}/src)

file(GLOB HEADERS "${INCLUDE_DIR}/*.h" "${INCLUDE_DIR}/subdirs/*.h" )
file(GLOB SOURCES "${SRC_DIR}/*.cpp" "${SRC_DIR}/subdirs/*.cpp"	)
	
source_group ("Header Files" FILES ${HEADERS})
source_group ("Source Files" FILES ${SOURCES})

add_executable (${PROJECT} ${SOURCES})
target_link_libraries(${PROJECT} thread rt)

Т.е. я не создают CMakeLists.txt в поддиректориях, у меня нет статических библиотек, все просто собирается в один бинарник.

Далее, я хочу добавить GTest. И вот тут у меня полный ступор. Могу ли я его добавить просто в этот корневой проект. Если да то имеет ли значение в каком месте?

enable_test()
set(PROJECT_TEST ${PROJECT}_test)
file(GLOB TEST_SRC_FILES ${PROJECT_SOURCE_DIR}/test/*.cpp)
add_executable(${PROJECT_TEST} ${TEST_SRC_FILES})
target_link_libraries(${PROJECT_TEST} pthread)
target_link_libraries(${PROJECT_TEST} rt)
add_test(${PROJECT_TEST} ${PROJECT_TEST})
add_dependency(${PROJECT_TEST} ${PROJECT})
Если делаю так, то у меня нет возможности обратить к тестируемым классам, потому что они не линкуются в тестовый бинарник. Если я пробую добавить исхоники проекта в тестовый проект, то у меня main функция тестового проекта замещается main функцией основного проекта. Либо я что то сделал нетак.

Вопрос, нужно ли мне разносить все свои исходники на Main часть и на все остальное в статическую библиотеку, которую подключать к тестам. Можно ли без вот этого разноса обойтись?

Cupper
()

Как вы добиваетесь отказоустойчивости ваших приложений

Форум — Development

Вам нужно что бы ваш сервер, маленький прокси или echo сервер работал всегда. Вы разработчик этого софта. Что вы предпримите.

Я не придумал ничего лучше чем:

1. Мой софт при запуске создает PID файл (для контроля повторного запуска и останова).

2. Я сделал скрипт который проверяет по этому PID файлу работает ли приложение. Если нет запускает его. (проверка по связке PID + имя процесса)

3. Повесил этот скрипт в крон с минутным интервалом.

Вроде бы рабочая конструкция получилась. Но что то не дает мне покоя. Не уж то и друге так делают. А если нет, то как ?

Cupper
()

Отсутствие ошибки при закрытии сокета

Форум — Development

За основу был взят вот этот пример

http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/allocation/s...

исключение, составляет то, что там для socket создается отдельный класс Session. Я делаю вот так

void DeviceTower::start_accept()
{
    boost::shared_ptr<boost::asio::ip::tcp::socket> socket(new boost::asio::ip::tcp::socket(io_service_));
    uint64_t session_id = add_session(socket);
    LOG("Create session %d", session_id);
    acceptor_.async_accept(*(socket.get()),
        boost::bind(&DeviceTower::handle_accept, this, session_id, socket, boost::asio::placeholders::error));
}

Т.е. я создаю сокет в обертке shared_ptr, кладу его в список активных (функция add_session), далее в обработчике

void DeviceTower::handle_accept(uint64_t id, boost::shared_ptr<boost::asio::ip::tcp::socket> socket,
		const boost::system::error_code& error)
{
	LOG("enter");
	if(error == boost::asio::error::operation_aborted)
	{
		LOG("Close acceptor on port [%d]", port_);
		delete_session(id);
	}
	else if(error)
	{
		LOG_ERR("An error occurred when the client connected: %s", error.message().c_str());
		delete_session(id);
	}
	else
	{
		start_accept();

		boost::shared_ptr<boost::array<char, 1024> > buff(new boost::array<char, 1024>());
		socket->async_read_some(boost::asio::buffer(*(buff.get())),
		        boost::bind(&DeviceTower::handle_read, this, id, socket, buff, boost::asio::placeholders::error));
	}
}

Я выполняю асинхронное чтение async_read_some.

Вопрос вот в чем. Когда мне нужно остановить мое приложение, мне нужно закрыть все сокеты что бы прервать все асинхронные операции что в свою очередь отпусти io_service.run()

void DeviceTower::stop()
{
	boost::system::error_code ec;
	acceptor_.close(ec);
	if(ec)
		LOG_ERR("Device [%s] err occurred while close acceptor: ", name(), ec.message().c_str());

	boost::mutex::scoped_lock lock(mtx_);
	SessionsMap::iterator it = openSession_.begin();
	for(; it != openSession_.end(); it++)
	{
		LOG("Call close for session %d", it->first);
		ec.clear();
		it->second->close(ec);
		if(ec)
			LOG_ERR("Error %s", ec.message().c_str());
	}
	while(!io_service_.stopped())
		boost::this_thread::sleep(boost::posix_time::seconds(1));
}

В документации Boost сказано что вызов close() на сокете приведет к тому что все зарегистрированные асинхронные операции, вызову свои коллбеки с ошибкой

boost::asio::error::operation_aborted

Для моего acceptor это происходит. Вызывается handle_accept с этой ошибкой. А вот для async_read_some не вызывается. И io_service.run() соответственно не отпускает управление.

Что я делаю не так? Я пробовал вызывать cancel, shutdown все безрезультатно :(.

Вызывать просто io_service.stop() я не хочу, потому что я не понимаю, что в этом случае случиться со всем зарегистрированными асинх. операциями.

 , ,

Cupper
()

Jenkins crushes

Форум — Admin

Столкнулся с такой странной проблемой. Был настроенный сервер Jenkins, работал недели две. Потом ни с того ни с сего начал падать. В логах это выглядит так

(process:4942): GLib-WARNING **: g_main_context_prepare(): main loop already active in another thread

GLib-ERROR **: file gmain.c: line 2008 (g_main_dispatch): assertion failed: (source)
aborting...

Выглядит это так, Jenkins запускается через Tomcat. Все это добро запускается, работает пару минут 2-10, и потом падает.

В гугле ниче толкового не нашел, ошибка имеет место быть в весьма редких случаях, решения проблемы не указано.

Может кто имел опыт?

java -version
java version "1.6.0_22"
OpenJDK Runtime Environment (IcedTea6 1.10.10) (rhel-1.28.1.10.10.el5_8-x86_64)
OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)
uname -a
Linux 3 2.6.18-308.11.1.el5 #1 SMP Tue Jul 10 08:48:43 EDT 2012 x86_64 x86_64 x86_64 GNU/Linux

Jenkins последний.

Cupper
()

Сложный инсталятор сложных вещей

Форум — Development

Название получилось немного громким, но оно в принципе раскрывает суть вопроса. У нас есть «система» которая пока состоит из 3 компонент, сервер-БД-вебморда. Хочется создать инсталятор который умел бы все это разворачивать на чистой системе или апдейтить там где уже было установлено.

Стандартный способ установки в виде паке сразу был отброшен так как он несет несколько другую цель, он нужен в первую очередь за тем что бы уметь установиться в системные дир и удалиться при необходимости.

У нас более сферический процесс установки. Который пока заключается в том что нужно установит либо

1. Все компоненты, или только выбранные. Параметризовать процесс установки (где развернуть БД, где веб морду)

2. Связать их все между собой (тобишь что бы параметры конфигов были согласованы)

3. Уметь обновляться, т.е. не стирать и заливать заново, а как то мержиться по заданным правилам.

В принципе все это можно сделать и на Bash, но хочется узнать может есть какие то не проприетарные средства нацеленные именно на создание сложных инсталяторов в Linux системах?

Cupper
()

Статическая сборка с boost на разных target

Форум — Development

Ведется разработка софта в ходе которой используется boost, так как постоянно приходится собираться и запускаться на разных системах то возникло желание делать статическую линковку c boost.

Но, гложет одно НО. По факту у нас две абсолютно разные системы в эксплуатации, это древний CentOS и Ubuntu 10ка, и не выйдет ли боком что собрав статический boost на CentOS и попробовав его слинковать на Ubuntu все ляжет, а еще хуже рухнет в runtime?

Статически хотим линковаться потому, что у нас кроме boost еще рад библиотек, и это уже стало головной больше следить на всеми зависимостями при динамической линковке.

Cupper
()

Есть ли способ прервать блокирующее чтение в ASIO?

Форум — Development

Не надо пожалуйста писать про non-blocking. Меня интересует лишь вопрос есть ли вообще корректный способ прервать блокирующую операцию в бусте.

Спасибо.

Cupper
()

Eclipse + Cmake

Форум — Development

Сразу вопрос, это нормально ? Если это нормально то почему я не могу сделать так что бы у меня

1. Было две сборки Release/Debug из коробки

2. Были доступны исходники при импорте проекта.

Кто имел опыт? Весь интернет мне говорит что Eclipse не умеет из коробки привязывать сорсы к проекту при импорте из Makefile. Так и есть?

Cupper
()

Плагинная архитектура

Форум — Development

Уверен что было и не раз, что то полезное даже уже нашел на форуме. Но никогда не было такой задачи, поэтому в голове небольшой хаос.

Задача: Есть некое устройство, оно на COM порт передает данные, нужно написать программу которая эти данные будет обрабатываться и взаимодействовать с остальной частью системы по сложному алгоритму.

Проблема в том что очень вероятно что после реализации приложения появятся другие устройства, которые будут уже совсем другие, да и данные другим образом передавать. Но с ними нужно будет работать абсолютно так же как и с первым.

Предполагаемое решение: Написать отдельную апликуху (так сказать core), к которой должен будет подключатся плагин для взаимодействия с конкретным девайсом, в данном случае который умеет читать с COM порта данные и знает как их интерпретировать.

Очень хочется, что бы написанную апликуху не нужно было пересобирать для каждого нового плагина/устройства. А что бы можно было собрать отдельно плагин, оттестировать и кинуть в прод.

На текущий момент условия такое, что бы не основное приложение запрашивало данные у плагина, а что бы плагин сам сообщал о том когда данные появились.

Но я вот чет не знаю как такое сотворить на С++. Нашел два вариант. Надо делать dll, dlopen и делать Си интерфейс. И весьма необычное решение в виде делать плагин отдельным приложением, которое например через заданные пайп передает данные в основное приложение.

Мне оба не нравятся. Подкиньте каких нибудь идей пожалуйста.

 

Cupper
()

eclipse juno Profile ID _SELF_ is not registered

Форум — Linux-install

Поставил последнюю Eclipse студию. Попробывал поставить плагин для Svn subversive. Вылезла ошибка «Profile ID _SELF_ is not registered» в инере вроде бы есть посты на эту тему, и ошибка довольно у многих, но как решить ее я чета и не понял. Если кто сталкивался и знает как побороть, подскажите пожалуйста.

Спасибо.

Cupper
()

Android plus C++ plus TCP

Форум — Development

Можете закидать меня тапками, но мне нужна ваша помощь.

Если я собрался сделать сетевое приложение на Android (возможно даже без графики) то к чему мне стоит готовиться ? К использованию беркли сокетов Linux, или исключительно API из NDK ?

так как я пока сам NDK не видал, и в инете вычитал что доки по нему в Online вообще нету, то пока я скачиваю его, возможно кто то направит меня на путь праведный, на какой нить howto...

если у кого то есть примеры проектов на С++ (без JAVA) для Android, с превеликой радостью приму их для изучения. Так же буду рад просто кускам кода показывающим ужас к которому нужно готовится.

Спасибо.

 ,

Cupper
()

[socket] выбор сетевого интерфейса

Форум — Development

Случился резкий паралич в мозгу. Я не как не могу сообразить как задать сетевой интерфейс с которого будет происходить рассылка данных.

Вот что у меня вызывает коллапс мысли: Для multicast при подключении к группе мы можем установить интерйфейс на котором ожидаем получать дейтаграммы

struct ip_mreq
{
        struct in_addr imr_multiaddr;   /* IP multicast address of group */
        struct in_addr imr_interface;   /* local IP address of interface */
};
Для мультикаст (в asio, незнаю названии опции для setsockopt) мы можем установить интерфейс с которого будут отправлять дейтаграммы через multicast::outbount_interface.

Для любого сокета мы может сделать bind указав в

struct sockaddr_in {
    short int          sin_family;  // Семейство адресов
    unsigned short int sin_port;    // Номер порта
    struct in_addr     sin_addr;    // IP-адрес
    unsigned char      sin_zero[8]; // "Дополнение" до размера структуры sockaddr
}; 
sin_addr = адрес нужного нам интерфеса.

Коллапс мысли вызывает наличие опции outbound_interface для Multicast в asio. Предполагается что это опция для setsockopt, а значит это для любого сокета (TCP/UDP) и как это коррелирует c bind ?

IP_MULTICAST_IF (IPV4-only) Sets the IPv4 interface address that is used to send outbound multicast datagrams. Multicast datagrams can be sent only on one interface at a time. The optvalue parameter is the IP address of the interface. This option returns 0 if it is successfully completed; otherwise, it returns the error number.

Хм... т.е. только для Multicast... а почему bind в этом случае устроил ?

 ,

Cupper
()

Узнать Multicast группу из входящей дейтаграммы

Форум — Development

И так, у меня есть проблема. Сервер вещает данные в UDP Multicast группу. Клиент подключается к нем и получает данные. Изменяем адрес группы (меняем IP, но не меняем порт) и клиент все равно получает данные.

Написал простенький receiver и пытаюсь в нем узнать из полученной дейтаграмма группу в которую он была отправлена. Что бы воочию увидеть что у меня сервер что то не правильно шлет или еще что то.

Не получается. Создаю сокет и настраиваю на UDP Multicast.

sockfd = socket(AF_INET, SOCK_DGRAM, 0)
устанавливаю ему опцию
setsockopt(sockfd, IPPROTO_IP, IP_PKTINFO, &optval, sizeof(optval)
заполняю структуру msghdr
char msg_buf[300];
	
    struct iovec iov;			// структура сообщения
    iov.iov_base = msg_buf;			// указываем buf в качестве буфера сообщения для iov
    iov.iov_len = sizeof(msg_buf);	// указываем размер буфера
	
	struct cmsghdr *cmsgptr;
	struct sockaddr_in cliaddr;
	msghdr msg;
	msg.msg_name = &cliaddr;					// задаем имя - структуру локального адреса
	msg.msg_namelen = sizeof(cliaddr);
	msg.msg_iov = &iov;						// указываем вектор данных сообщения
    msg.msg_iovlen = 1;
получаю Дейтаграмму
recvmsg(receiver, &msg, 0)
Пытаюсь извлечь нужные данные
			for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
			{
				std::cout << "Ohhh...\n";			
				struct in_pktinfo *pi = (struct  in_pktinfo* )CMSG_DATA(cmsgptr);
				// at this point, peeraddr is the source sockaddr
				// pi->ipi_spec_dst is the destination in_addr
				// pi->ipi_addr is the receiving interface in_addr
				std::cout << inet_ntoa(pi->ipi_spec_dst) << std::endl;
			}
Но CMSG_FIRSTHDR(&msg) возвращает NULL. В чем может быть беда?

Подумал, что может быть при отправке не указывается нужные данные. Но Wariesshark под виндой для моих дейтаграм корректно указывает Destination.

 , , ,

Cupper
()

что значит параметр optval у функции setsockopt

Форум — Development

В гугл с именно таким и многими похожими запросами я обращался. И маны читал, и на русском и на буржуйском.

Но вот такое описание

Параметры optval и optlen используются в функции setsockopt для доступа к значениям флагов.
ну ни фига не понятно. Во всех интернетах вижу одно и тоже
const int n=1;
 setsockopt(..., ..., ..., n, sizeof(n)). 

что единица ? зачем единица ? такое чувство что просто просто 1 и все. И другого быть не может. Но я видел код где и 5 передавали...

На http://www.rsdn.ru/article/net/keep_alive.xml всетаки удалось найти чуть больше информации

Для включения/выключения посылки keep-alive используется опция SO_KEEPALIVE уровня SOL_SOCKET. Параметр optval интерпретируется функцией как булево значение, для включения посылки он должен иметь значение TRUE, иначе – FALSE.
А для всех остальных опций ? Вопрос какого хера bool'ево значение передается таким неепическим способом я не задаю, догадываюсь что для разных опций этот указатель и на структуру может указывать.

Подскажите пожалуйста.

 optval, setsockopt

Cupper
()

RSS подписка на новые темы