正在作为Linux服务运行时,工作程序会引发xercesc_3_2 :: TranscodingException

问题描述 投票:0回答:1

我有一个程序,该程序使用Xerces XML framework读取RSS提要,并使用得到的信息“处理”。

该程序有效。

但是,如果通过Linux服务(以service myservice.sh start开头的init.d脚本)以任何方式运行程序,则在读取某些亚洲供稿时,程序将抛出xercesc_3_2::TranscodingException

如果直接从init脚本或wrapper> myProgram或wrapper1> wrapper2> myProgram等调用该程序,则会引发异常。

我真的不知道为什么该程序无论是从命令行运行还是从init脚本运行都有不同的表现。

环境

Centos 6, 64-bit 4.4.211-1.el6.elrepo.x86_64 
C++ '11 
Xerces-C 3.2.1

这里是一个最小的测试用例。

XML测试文件:

<?xml version="1.0" encoding="utf-8" ?>
<rdf:RDF xml:lang="ja" xmlns="http://purl.org/rss/1.0/" 
    xmlns:dc="http://purl.org/dc/elements/1.1/" 
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
    xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" >
<item>
 <title>「これまで採択した企画」を更新しました。</title>
 <link>http://www.nhk.or.jp/kikakubosyuu/koremade.html?=20200430T1200</link>
 <dc:date>2020-04-30T17:00+09:00</dc:date>
 <description> </description>
</item>
</rdf:RDF>

对第一个<title>contents(即“これまで采coding企画”を更新しました。”进行转码时,会引发异常。)。但是同样,仅当作为服务运行时。

从启动脚本运行和从Shell运行有什么区别?为什么会出现[[Transcode错误?对我来说没有意义。

更新I

今天,我了解到main传递给了main(int argc, char **argv, char **envp)中的环境变量。以前不知道。

我修改了程序以在启动时转储其环境变量。请参阅下面的修改后的源代码。

环境变量

NOT

相同。作为服务运行时,仅设置了以下几个变量:

SHELL=/bin/bash TERM=xterm-color PATH=/sbin:/usr/sbin:/bin:/usr/bin _=/mnt/swdevel/Pelican/source_build/src/overlay/testXmlTranscodeBug PWD=/ HOME=/root SHLVL=2

列表中明显缺少的是

LANG = en_US.UTF-8

。请参阅下面的答案。

Init脚本片段

STARTSCRIPT=/path/to/rssReaderProg /path/To/Test/Input/File start() { msg="Starting service" writeSysLog "$msg" echo $msg >&2 local CMD="$STARTSCRIPT &>> \"$LOGFILE\" & echo \$!" su -c "$CMD" $RUNAS > "$PIDFILE" chmod 644 $LOGFILE msg='RSS service started' echo $msg >&2 writeSysLog "$msg" }

阅读器测试源代码

#include <stdio.h> #include <string> #include "xercesc/dom/DOM.hpp" #include "xercesc/dom/DOMException.hpp" #include "xercesc/dom/DOMNodeList.hpp" #include "xercesc/dom/DOMNamedNodeMap.hpp" #include "xercesc/dom/DOMNode.hpp" #include "xercesc/dom/DOMAttr.hpp" #include "xercesc/dom/DOMError.hpp" #include "xercesc/dom/DOMErrorHandler.hpp" #include "xercesc/sax/HandlerBase.hpp" #include "xercesc/util/XMLString.hpp" #include "xercesc/dom/DOMLocator.hpp" #include "xercesc/parsers/XercesDOMParser.hpp" #include "xercesc/util/OutOfMemoryException.hpp" XERCES_CPP_NAMESPACE_USE int main(int argc, char **argv, char **envp) { printf("\n\nENV Array:\n"); for (char **env = envp; *env != 0; env++) { char *thisEnv = *env; printf("%s\n", thisEnv); } printf("\n\n"); if (argc != 2) { printf("Usage: testXmlTranscodeBug <xmlFilePath>\n"); exit(1); } printf("initializing XML\n"); XMLPlatformUtils::Initialize(); DOMDocument *pDoc = 0; DOMElement *pDocRoot = 0; XercesDOMParser *pParser = new XercesDOMParser(); pParser->setValidationScheme(XercesDOMParser::Val_Always); char *filePath = argv[1]; XMLCh *pItemTag = XMLString::transcode("item"); printf("Opening %s\n", filePath ); pParser->parse(filePath); pDoc = pParser->getDocument(); pDocRoot = pDoc->getDocumentElement(); // Search for all the <item> child elements under pTopElem which DOMNodeList *pItemList = pDocRoot->getElementsByTagName(pItemTag); int numItems = pItemList->getLength(); printf("Found %d items\n", numItems ); for (int i = 0; i < numItems; i++) { printf(" ITEM %d\n", i); DOMNode *pItemNode = pItemList->item(i); DOMElement *pItemItem = ( (DOMElement *) pItemNode)->getFirstElementChild(); while (pItemItem != 0) { char *en = XMLString::transcode(pItemItem->getTagName()); printf(" TAG '%s'\n", en); std::string elemName(en); XMLString::release(&en); // The item value (text content) is first child. It might be blank DOMNode *pValNode = pItemItem->getFirstChild(); if (pValNode != 0) { printf(" pValNode = %p, print node value\n", pValNode); const XMLCh *nodeVal = pValNode->getNodeValue(); printf(" nodeVal=%p, len=%lu\n", nodeVal, strlen((char*)nodeVal)); printf(" calling transcode. print node value\n"); char *val = 0; try { val = XMLString::transcode(pValNode->getNodeValue()); } catch (...) { printf(" EXCEPTION Calling XMLString::transcode()\n"); } printf(" transcode returned [%s]\n", val); XMLString::release(&val); } printf("\n"); pItemItem = pItemItem->getNextElementSibling(); } } }
linux xerces xerces-c
1个回答
0
投票
作为服务启动时,未在环境中设置

LANG = en_US.UTF-8。

这似乎导致Xerces转码器有时因xercesc_3_2 :: TranscodingException而失败。

目前,我已经将LANG=en_US.UTF-8硬编码到程序中,并且它不再引发异常。

int main(int argc, char **argv) { putenv("LANG=en_US.UTF-8"); etc...

© www.soinside.com 2019 - 2024. All rights reserved.