首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >工作程序在作为linux服务运行时抛出xercesc_3_2::TranscodingException。

工作程序在作为linux服务运行时抛出xercesc_3_2::TranscodingException。
EN

Stack Overflow用户
提问于 2020-05-03 12:30:03
回答 1查看 361关注 0票数 0

我有一个程序,它使用Xerces XML框架读取一个RSS提要,并使用它获得的信息“做一些事情”。

这个程序很管用。

但是,如果程序以任何方式通过Linux服务运行(init.d脚本启动为service myservice.sh start),则程序在读取某些亚洲提要时抛出一个xercesc_3_2::TranscodingException

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

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

环境

代码语言:javascript
复制
Centos 6, 64-bit 4.4.211-1.el6.elrepo.x86_64 
C++ '11 
Xerces-C 3.2.1

下面是一个最小的测试用例。

XML测试文件:

代码语言:javascript
复制
<?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> (即“これまで採択した企画”を更新しました“)的内容时,会引发异常。。但同样,只有在作为服务运行的情况下。

从init脚本运行和从shell运行有什么不同?翻译错误有什么原因吗?对我来说没有意义。

更新I

今天,我了解了main是传递环境变量的,就像在main(int argc, char **argv, char **envp)中一样。以前都不知道。

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

环境变量是,而不是

在作为服务运行时,只有以下几个变量集:

代码语言:javascript
复制
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脚本片段

代码语言:javascript
复制
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"
}

阅读器测试源代码

代码语言:javascript
复制
#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();
        }
    }

}
EN

回答 1

Stack Overflow用户

发布于 2020-05-04 01:49:36

当作为服务启动时,LANG=en_US.UTF-8不会在环境中设置。

这似乎会导致Xerces代码转换程序有时在xercesc_3_2::TranscodingException中失败。

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

代码语言:javascript
复制
int
main(int argc, char **argv)
{
    putenv("LANG=en_US.UTF-8");
    etc...
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61574460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档