加载论坛时出错,请强制刷新页面重试。

龙芯的声卡驱动导致MAME模拟器segment fault?

EMCA

编译好的MAME模拟器可以显示管理界面

但是运行任何游戏都会显示segment fault,退出时也会发生segment fault

用gdb调试,发现出问题的是sound.cpp,发生segment fault后打印backtrace显示如下信息

(gdb) backtrace

#0 0x0000000000000078 in ?? ()

#1 0x0000000121d58d40 in util::detail::delegate_base<delegate_late_bind, void, sound_stream&, std::vector<read_stream_view, std::allocator<read_stream_view> > const&, std::vector<write_stream_view, std::allocator<write_stream_view> >&>::operator() (this=0x124b1c000, this=0x124b1c000, args#2=std::vector of length 1, capacity 1 = {...},

args#1=std::vector of length 0, capacity 0, args#0=...) at ../../../../../src/lib/util/delegate.h:760

#2 sound_stream::update_view (this=this@entry=0x124b1bee0, start=..., end=..., outputnum=<optimized out>, outputnum@entry=0) at ../../../../../src/emu/sound.cpp:742

#3 0x0000000121d5905c in sound_stream::update (this=0x124b1bee0) at ../../../../../src/emu/attotime.h:100

#4 0x000000012012d6e0 in non-virtual thunk to dac_byte_device_base::write(unsigned char) () at /usr/include/c++/8/ext/new_allocator.h:86

#5 0x0000000120c9bb44 in devcb_write<unsigned char, (unsigned char)255>::operator()(unsigned int, unsigned char, unsigned char) ()

at /usr/include/c++/8/bits/shared_ptr_base.h:404

#6 0x00000001202bce94 in addressable_latch_device::update_bit (this=0x1241dff00) at ../../../../../src/devices/machine/74259.cpp:216

#7 addressable_latch_device::enable_w (state=0, this=0x1241dff00) at ../../../../../src/devices/machine/74259.cpp:184

#8 addressable_latch_device::write_bit (d=<optimized out>, offset=<optimized out>, this=0x1241dff00) at ../../../../../src/devices/machine/74259.cpp:153

#9 addressable_latch_device::write_d0 (this=0x1241dff00, offset=<optimized out>, data=<optimized out>) at ../../../../../src/devices/machine/74259.cpp:241

#10 0x0000000120c3f534 in tms99xx_device::cru_output_operation (this=0x1241cd500) at ../../../../../src/lib/util/coretmpl.h:594

#11 0x0000000120c4534c in tms99xx_device::execute_run (this=0x1241cd500) at ../../../../../src/devices/cpu/tms9900/tms9900.cpp:1254

#12 0x0000000121d2b560 in device_execute_interface::run (this=0x1241cd7f0) at ../../../../../src/emu/diexec.h:189

#13 device_scheduler::timeslice (this=this@entry=0xffffff6128) at ../../../../../src/emu/schedule.cpp:456

#14 0x0000000121cc1e34 in running_machine::run (this=this@entry=0xffffff0ef0, quiet=quiet@entry=false) at ../../../../../src/emu/machine.cpp:348

#15 0x000000012273bee0 in mame_machine_manager::execute (this=this@entry=0x124059e20) at ../../../../../src/frontend/mame/mame.cpp:288

#16 0x00000001227e0c74 in cli_frontend::start_execution (this=this@entry=0xffffff6938, manager=manager@entry=0x124059e20, args=std::vector of length 3, capacity 3 = {...})

at ../../../../../src/frontend/mame/clifront.cpp:277

#17 0x00000001227e106c in cli_frontend::execute (this=this@entry=0xffffff6938, args=std::vector of length 3, capacity 3 = {...})

at ../../../../../src/frontend/mame/clifront.cpp:293

#18 0x00000001227385cc in emulator_info::start_frontend (options=..., osd=..., args=std::vector of length 3, capacity 3 = {...})

at ../../../../../src/frontend/mame/mame.cpp:453

#19 0x00000001200d3b68 in main (argc=<optimized out>, argv=<optimized out>) at ../../../../../src/osd/sdl/sdlmain.cpp:100

(gdb)

看调试信息似乎是mame的声音处理导致的segment fault,是否是龙芯声卡驱动不支持这种纯用时间轴实现的游戏?但我的另一块板子,板载的格兰菲的声卡,却无此问题。

而且在新世界系统里用龙芯板载声卡有同样的问题,所以怀疑应当是声卡驱动的问题


EMCA

最新进展,显示了画面,但是还是在初始化声卡时崩溃,

同样是访问内存0x78时发生segment fault,不知道是不是触发了内存保护


EMCA

希望将来能成功运行,可以买个龙芯派玩三国战纪


lizhuojian

EMCA 手持3a6000期待中


EMCA

昨天闲来无事,追踪了下bug来源,感觉与声卡驱动的关联不大,有可能是C++ STL库里Vector的实现和龙芯系统的内存管理机制的冲突造成的

由于MAME是模拟器,而且似乎是实时解释执行的,会将被模拟的主机上的一些端口的读写操作映射成本地的端口调用,类似这样(以之前运行的looping游戏的源码looping.cpp为例)

looping_state::map(address_map &map)

{

...

map(0xf800, 0xf800).mirror(0x03fc).portr("P1").w(FUNC(looping_state::out_0_w));

...

}

将被模拟主机的0xf800端口的写操作映射至looping_state::out_0_w方法

其中map(<start>, <end>)是一个操作符重载(重载了“()”),是这样实现的

address_map_entry &address_map::operator()(offs_t start, offs_t end)

{

address_map_entry *ptr = new address_map_entry(*m_device, *this, start, end);

m_entrylist.append(*ptr);

return *ptr;

}

然后looping_state::looping函数中使用m_maincpu->set_addrmap(AS_PROGRAM, &looping_state::map)方法将looping_state::map中定义的端口操作处理函数写入模拟器的端口动作表m_address_map

函数set_addrmap在dimemory.cpp中是这样实现的

void device_memory_interface::set_addrmap(int spacenum, address_map_constructor map)

{

   assert(0 <= spacenum);

  if (spacenum >= int(m_address_map.size()))                            

          m_address_map.resize(spacenum + 1);                           

  m_address_map[spacenum] = std::move(map);                             

}

先调整m_address_map这个vector的大小然后将本地函数等信息用std::move填进去,怀疑segment fault就是在这个环节里造成的

接下来的模拟器地址0x78读操作引发segment fault的问题就涉及龙芯系统的内存管理机制和STL库里vector类型的实现问题了,m_address_map这个vector变量在返回端口处理函数时大概率引发了内存保护问题,这超出了我的能力,到这里只能把问题上报


liudidi

EMCA 最新的275仍然是这个问题,看起来官方可能不会解决了。


EMCA

liudidi 异常发生在delegate.h,应该是/src/lib/util/delegate.h和delegate.cpp里的问题,里面有三种工作机制,根据软硬件架构不同编译器会选取不同的工作机制

#define MAME_DELEGATE_TYPE_COMPATIBLE 0

#define MAME_DELEGATE_TYPE_ITANIUM 1

#define MAME_DELEGATE_TYPE_MSVC 2

感觉这个bug和MAME源码关系不大,似乎还是因为龙芯的内存保护机制,导致0x0000000000000078这块内存里的指令或数据无法访问,这个要么和编译器有关要么和系统有关,由于MAME代码里用了大量的C++模板,很难调试而且让人感觉很费解,具体问题我正在看


liudidi

mame弄不好,raine稍修改下到是可以运行。


gainer

手持3a6000期待中


知识共享许可协议
本站文章除其作者特殊声明外,一律采用CC BY-NC-SA 4.0许可协议进行授权。
进行转载或二次创作时务必以相同协议进行共享,严禁用于商业用途